Skip to content
This repository was archived by the owner on Apr 7, 2020. It is now read-only.

Commit b87cff2

Browse files
author
caizhenxing
committed
增加command和event装饰器
1 parent 5be6630 commit b87cff2

File tree

14 files changed

+324
-30
lines changed

14 files changed

+324
-30
lines changed

.babelrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
22
"presets": ["es2015", "stage-1"],
3-
"plugins": ["transform-runtime"]
3+
"plugins": ["transform-runtime", "transform-decorators-legacy"]
44
}

README.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ cqrs.publishCommand('createAccount',
4040

4141
** App不要创建多个实例,整个系统都是单例的 **
4242

43-
## 使用
43+
## 开发
4444

4545
模块采用面向对象的开发
4646

@@ -177,6 +177,24 @@ export default class AccountEventHandler extends EventHandler {
177177
}
178178
```
179179
180+
处理其他模块的事件可以用command或event装饰器实现
181+
182+
```js
183+
import {command,event} from 'cqrs-fx';
184+
185+
export default class AccountCommandHandler2 extends CommandHandler {
186+
@command('module1/createAccount')
187+
createAccount2(message) {
188+
console.log('AccountCommandHandler2 createAccount2 ok');
189+
}
190+
191+
@command('module1', 'createAccount')
192+
createAccount3(message) {
193+
console.log('AccountCommandHandler2 createAccount3 ok');
194+
}
195+
}
196+
```
197+
180198
## 配置性 && 扩展性:
181199
182200
可以通过构造App实例时配置系统
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import {CommandHandler,command} from '../../../src';
2+
3+
export default class AccountCommandHandler2 extends CommandHandler {
4+
@command('module1/createAccount')
5+
createAccount2(message) {
6+
console.log('AccountCommandHandler2 createAccount2 ok');
7+
}
8+
9+
@command('module1', 'createAccount')
10+
createAccount3(message) {
11+
console.log('AccountCommandHandler2 createAccount3 ok');
12+
}
13+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import {CommandHandler, command} from '../../../src';
2+
3+
export default class BookCommandHandler extends CommandHandler {
4+
createBook(message) {
5+
console.log('create book');
6+
}
7+
8+
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"babel-cli": "^6.24.1",
3535
"babel-core": "^6.24.1",
3636
"babel-loader": "^6.2.4",
37+
"babel-plugin-transform-decorators-legacy": "^1.3.4",
3738
"babel-plugin-transform-runtime": "^6.9.0",
3839
"babel-preset-es2015": "^6.5.0",
3940
"babel-preset-react": "^6.5.0",

src/bus/bus.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1-
import {isString} from '../utils';
1+
import {isString, log} from '../utils';
22
import i18n from '../i18n';
33

44
export default class Bus {
55
messageQueue = []
66

7+
_committed = true;
8+
9+
get committed() {
10+
return this._committed;
11+
}
12+
713
constructor(type) {
814
this.type = type;
915
}
@@ -19,18 +25,16 @@ export default class Bus {
1925
}
2026
for (let msg of messages) {
2127
if (!msg) {
28+
log(i18n.t('无效消息跳过'))
2229
continue;
2330
}
2431
this.messageQueue.push(msg);
32+
this._committed = false;
2533
}
2634
}
2735

2836
clear() {
2937
this.messageQueue.length = 0;
3038
}
3139

32-
async commit() {}
33-
34-
async rollback() {}
35-
3640
}

src/bus/direct_bus.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,26 @@ import {log} from '../utils';
44
import i18n from '../i18n';
55

66
export default class DirectBus extends Bus {
7+
8+
_backupMessageArray;
9+
10+
711
async commit() {
8-
log(i18n.t('提交分发'));
12+
log(i18n.t('总线提交'));
913
const dispatcher = getDispatcher(this.type);
14+
this._backupMessageArray = [...this.messageQueue];
1015
this.messageQueue.forEach(async(msg) => {
1116
await dispatcher.dispatch({type: this.type, module: msg.module, name: msg.name, data: msg.data});
1217
});
18+
this._committed = true;
1319
this.messageQueue.length = 0;
1420
}
1521

1622
async rollback() {
17-
await getRepository().rollback();
18-
log(i18n.t('回滚存储'));
23+
if (this._backupMessageArray && this._backupMessageArray.length > 0) {
24+
this.messageQueue = [...this._backupMessageArray];
25+
}
26+
this._committed = false;
27+
log(i18n.t('总线回滚'));
1928
}
2029
}

src/bus/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export function getDispatcher(type) {
3131
if (!(dispatcher instanceof Dispatcher)) {
3232
throw new Error(err.configFailed, type + i18n.t('消息分发器未正确配置,可以在config/bus.js中指定'));
3333
}
34+
dispatcher.createAndRegisterAlias();
3435
fxData.container[type + 'Dispatcher'] = dispatcher;
3536
}
3637

src/bus/message_dispatcher.js

Lines changed: 76 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,79 @@ import {log, isFunction, isString} from '../utils';
22
import {fxData, _require} from '../core';
33
import i18n from '../i18n';
44
import Dispatcher from './dispatcher';
5+
import {getDecoratorToken} from '../command/decorator';
6+
import assert from 'assert';
57

68
export default class MessageDispatcher extends Dispatcher {
79
_dispatchingListeners = []
810
_dispatchFailedListeners = []
911
_dispatchedListeners = []
1012

11-
getHandlers(module, name) {
12-
return Object.keys(fxData.alias).filter(item => item.startsWith(`${module}/${this.type}/`)).map(alias => _require(alias)).filter(item => isFunction(item.prototype[name]));
13+
_handlers = {};
14+
15+
createAndRegisterAlias() {
16+
Object.keys(fxData.alias).filter(item => item.indexOf(`/${this.type}/`) > -1).map(alias => _require(alias)).forEach((type)=>this.registerHandler(type));
17+
}
18+
19+
getHandlers(name, module) {
20+
assert(name);
21+
if (!module) {
22+
const mn = name.split('/');
23+
module = mn[0];
24+
name = mn[1];
25+
}
26+
assert(module);
27+
return this._handlers[`${module}/${name}`] || [];
28+
}
29+
30+
registerHandler(handlerType) {
31+
let ctoken = getDecoratorToken(handlerType);
32+
if (!ctoken.name && !ctoken.module) {
33+
ctoken = {
34+
module: handlerType.prototype.__module,
35+
name: handlerType.name
36+
};
37+
}
38+
for (const p of Object.getOwnPropertyNames(handlerType.prototype)) {
39+
if (p === 'constructor'){
40+
continue;
41+
}
42+
if (!isFunction(handlerType.prototype[p])){
43+
continue;
44+
}
45+
const {
46+
module = ctoken.module,
47+
name =p
48+
} = getDecoratorToken(handlerType.prototype[p]);
49+
if (module && name) {
50+
let items = this._handlers[`${module}/${name}`];
51+
if (!items) {
52+
this._handlers[`${module}/${name}`] = items = [];
53+
}
54+
items.push({CLS: handlerType, method: p});
55+
}
56+
}
57+
}
58+
59+
unregisterHandler(handler) {
60+
const ctoken = getDecoratorToken(handlerType);
61+
for (const p in handlerType.prototype) {
62+
const {
63+
module = ctoken.module,
64+
name
65+
} = getDecoratorToken(handlerType.prototype[p]);
66+
if (module && name) {
67+
let items = this._handlers[`${module}/${name}`];
68+
if (!items) {
69+
continue;
70+
}
71+
const item = items.find(item => item.CLS === handler);
72+
if (!item) {
73+
continue;
74+
}
75+
items.splice(items.indexOf(item), 1);
76+
}
77+
}
1378
}
1479

1580
// message = {name,module,type,data}
@@ -48,35 +113,32 @@ export default class MessageDispatcher extends Dispatcher {
48113
if (!handlers || handlers.length <= 0) {
49114
log(i18n.t('无消息处理器'));
50115
}
51-
let success = 0;
52-
for (const type of handlers) {
53-
var CLS = _require(type);
54-
if (!CLS || !isFunction(CLS))
55-
continue;
116+
for (const {CLS, method}
117+
of handlers) {
56118
var handler = new CLS();
57-
if (!handler || !isFunction(handler[name]))
119+
if (!isFunction(handler[method])) {
120+
log(i18n.t('处理器无法执行命令'));
58121
continue;
122+
}
59123
const evt = {
60124
type: message.type,
61125
data: message.data,
62126
module,
63127
name,
64128
handler
65129
};
66-
log(i18n.t('开始分发') + this.type + ':' + `${module}/${name}`);
130+
log(i18n.t('开始执行') + this.type + ':' + `${module}/${name}`);
67131
this._onDispatching(evt);
68132
try {
69-
await handler[name].bind(handler)(message.data || {});
133+
await handler[method].bind(handler)(message.data || {});
70134
this._onDispatched(evt);
71-
success++;
72-
log(i18n.t('完成分发') + this.type + ':' + `${module}/${name}`);
135+
log(i18n.t('完成执行') + this.type + ':' + `${module}/${name}`);
73136
} catch (err) {
74137
evt.error = err;
75-
log(i18n.t('失败分发') + this.type + ':' + `${module}/${name}` + ',' + err);
138+
log(i18n.t('失败执行') + this.type + ':' + `${module}/${name}` + ',' + err);
76139
this._onDispatchFaild(evt);
77140
}
78141
}
79-
return success;
80142
}
81143

82144
clear() {

src/command/decorator.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import {log, isFunction} from '../utils'
2+
import i18n from '../i18n';
3+
4+
export function getDecoratorToken(fn) {
5+
if (!isFunction) {
6+
log(i18n.t('不是有效的command'))
7+
return;
8+
}
9+
return {name: fn.__commandName, module: fn.__commandModule};
10+
}
11+
12+
export function module(module) {
13+
return (fn) => {
14+
if (!isFunction) {
15+
log(i18n.t('无法定义command属性'));
16+
return;
17+
}
18+
if (module) {
19+
if (fn.__commandModule) {
20+
log(i18n.t('command属性冲突'));
21+
}
22+
fn.__commandModule = module;
23+
}
24+
return fn;
25+
}
26+
}
27+
28+
export function command(...moduleOrNames) {
29+
return (target, fnName, fn) => {
30+
if (!isFunction) {
31+
log(i18n.t('无法定义command属性'));
32+
return;
33+
}
34+
let module,
35+
name = fnName;
36+
if (moduleOrNames.length === 1) {
37+
const mn = moduleOrNames[0].split('/');
38+
if (mn.length == 2) {
39+
module = mn[0];
40+
name = mn[1];
41+
} else {
42+
module = moduleOrNames[0];
43+
name = null;
44+
}
45+
} else if (moduleOrNames.length == 2) {
46+
module = moduleOrNames[0];
47+
name = moduleOrNames[1];
48+
} else {
49+
log(i18n.t('command属性无效'));
50+
}
51+
if (module) {
52+
if (fn.value.__commandModule) {
53+
log(i18n.t('command属性冲突'));
54+
}
55+
fn.value.__commandModule = module;
56+
}
57+
if (name) {
58+
if (fn.value.__commandModule) {
59+
log(i18n.t('command属性冲突'));
60+
}
61+
fn.value.__commandName = name;
62+
}
63+
return fn;
64+
}
65+
}

0 commit comments

Comments
 (0)