使用发布订阅模式实现LazyMan的链式调用
class _lazyMan {
constructor(name) {
this._name = name;
this._taskList = [];
this._subscribe('lazyMan', name);
setTimeout(() => {
this._taskList.reverse();
this._publish();
});
}
_subscribe(msg, ...args) {
if (msg === 'sleepFirst') this._taskList.unshift({msg: 'sleep', args});
else this._taskList.push({msg, args});
}
_publish() {
if (this._taskList.length > 0) {
this._run(this._taskList.pop());
}
}
_run(option) {
const {msg, args} = option;
switch (msg) {
case 'lazyMan':
this._lazyMan(...args);
break;
case 'sleep':
this._sleep(...args);
break;
case 'eat':
this._eat(...args);
break;
default:
break;
}
}
_log(text) {
const prefix = '运行输出:';
console.log(`${prefix}${text}`);
}
_lazyMan(name) {
this._log(`你好,${name}`);
this._publish();
}
_sleep(time) {
this._log(`${this._name}正在睡觉,预计${time}秒...`);
setTimeout(() => {
this._log(`${this._name}在${time}秒后醒了`);
this._publish();
}, time * 1000);
}
_eat(name) {
this._log(`${this._name}正在吃${name}`);
this._publish();
}
sleep(time) {
this._subscribe('sleep', time);
return this;
}
sleepFirst(time) {
this._subscribe('sleepFirst', time);
return this;
}
eat(name) {
this._subscribe('eat', name);
return this;
}
showProcedure() {
const procedure = this._taskList.map(({msg, args}) => `${msg}(${args.join(', ')})`);
console.log('事件流程:' + procedure.join(' -> '));
}
}
function lazyMan(name) {
return new _lazyMan(name);
}
const lm = lazyMan('魏鑫');
lm.eat('早饭').sleep(1).eat('午饭').sleep(2).eat('晚饭').sleepFirst(8);
lm.showProcedure(); // sleep(8) -> eat(早饭) -> sleep(1) -> eat(午饭) -> sleep(2) -> eat(晚饭)
lm.eat('粑粑').sleep(3).eat('奥里给');
lm.showProcedure(); // sleep(8) -> eat(早饭) -> sleep(1) -> eat(午饭) -> sleep(2) -> eat(晚饭) -> eat(粑粑) -> sleep(3) -> eat(奥里给)