发布订阅模式实现LazyMan

使用发布订阅模式实现LazyMan的链式调用

插图
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(奥里给)

版权

本作品采用 CC BY-NC-ND 4.0 授权。