JavaScript中的协程与生产者消费者模式

JavaScript中的协程以及实现生产者消费者模式

插图
生产者消费者模式输出示例
class Apple {
    static price = 10;
    constructor() {
        this.type = '红富士';
        this.location = '邯郸';
        this.taste = '甜';
        this.price = Apple.price;
    }
    toString() {
        return `[${Apple.name}] {type: ${this.type}, loc: ${this.location}, taste: ${this.taste}, price: ${this.price}}`;
    }
}

class Penapple {
    static price = -817;
    constructor() {
        this.type = '呆湾凤梨';
        this.location = '呆湾';
        this.taste = '酸';
        this.price = Penapple.price;
    }
    toString() {
        return `[${Penapple.name}] {type: ${this.type}, loc: ${this.location}, taste: ${this.taste}, price: ${this.price}}`;
    }
}

function produce (Goods) {
    function make (cName, i, delay = 1000) {
        console.log(`[生产者] 正给${cName}生产第${i}${Goods.name}...,预计需要${delay}ms`);
        return new Promise(resolve => {
            setTimeout(() => {
                resolve(new Goods());
            }, delay);
        });
    }
    return async function (c, num, delay) {
        const cName = c.next().value;
        for (let i = 1; i <= num; i++) {
            const freshGoods = await make(cName, i, delay);
            const cRes = c.next(freshGoods).value;
            console.log(`[消费者反馈] ${cRes}`);
        }
    }
}

function* consumer (name) {
    let r = name;
    let n;
    while (true) {
        n = yield r;
        if (!n) {
            r = '没给我东西啊!';
            continue;
        }
        console.log(`[消费者 ${name}] 正买 ${n}`);
        r = `我是${name},我买完了`;
    }
}

function fruitFactory (fruit) {
    const fruitMap = {
        'apple': Apple,
        'penapple': Penapple,
    };
    if (!(fruit in fruitMap)) throw `这个工厂不能生产 ${fruit}`;
    return produce(fruitMap[fruit]);
}

(async function main() {
    const appleProducer = fruitFactory('apple');
    const penappleProducer = fruitFactory('penapple');
    
    appleProducer(consumer('魏鑫'), 1, 5000);
    await penappleProducer(consumer('张艳'), 5);
    Penapple.price = 250;
    penappleProducer(consumer('魏鑫'), 1, 2000);
})();

版权

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