使用事件订阅/发布模拟简单的生产者/消费者模型遇到的问题
发布于 3 个月前 作者 kylind 368 次浏览 来自 问答

我想实现的功能是生产者生产一批数据后, 触发full事件。 消费者开始消费数据, 消费之后,触发empty事件, 生产者开始生产数据…

下面的代码执行的结果是生产者生产了数据之后,消费者消费了数据, 但不能触发生产者再造数据了。 因为我侦错到Empty的生产者监听器数量为0. 这是为什么? 1.index文件

var event_pattern = require('./event_pattern');
var readline = require('readline');
var util = require('util');

//实例化一个生产者和两个消费者
var producer = new event_pattern.Producer();

var consumer1 = new event_pattern.Consumer('A');
var consumer2 = new event_pattern.Consumer('B');
//消费者订阅生产者full事件
producer.on('full', consumer1.consume);
producer.on('full', consumer2.consume);
//生产者订阅消费者empty事件
consumer1.on('empty', producer.produce);
consumer2.on('empty', producer.produce);

producer.produce();

2.生产者与消费者模块

var events = require('events');
var console = require('console');
var util = require('util');

function Producer() {

    events.EventEmitter.call(this);

    var totalCount = totalCount || 100;

    var currentCount=0;

    this.produce = function(beans) {

        if (!util.isArray(beans)) {
            beans = [];
        }

        var i = 0;
        var bean;

        while (i < 18 && currentCount++ < totalCount) {

            bean = Math.round(Math.random() * 100);

            beans.push(bean);

            console.log("produce: " + bean);

            i++;

        }

        console.log("full listeners: " + this.listenerCount('full'));
        this.emit('full', beans, this);

    };

};

util.inherits(Producer, events.EventEmitter);

function Consumer(name) {

    events.EventEmitter.call(this);

    this.name = name;

    this.consume = function(beans) {

        var i = 0;

        while (i < 10 && beans.length > 0) {
            var bean = beans.shift();
            console.log(name + "consume: " + bean);
            i++;
        }

        if (beans.length == 0) {
             console.log("empty listeners: " + this.listenerCount('empty'));//值为0,为什么没有任何监听器了?????
            var hasListeners = this.emit('empty', beans);
        }

    };

}

Consumer.prototype=new events.EventEmitter();
Consumer.prototype.constructor=Consumer;
10 回复

自己顶,有帮忙解答一下这个的问题的吗? 这个问题困扰我两天了

只能这么说,如果想要继承EventEmitter,最好这么用

function Consumer(){
	EventEmitter.call(this);
	// others
}

其他的我也看不下去

事实上,我正是这么写呢1

如果用两个nodejs进程,一个生产,一个消费, 之间用send/on(‘message’,callback) 来通信呢

我不是很明白哈,是

this.consume

还是想

Producer.prototype.consume

@reverland 我试过了不是这里的问题

@yakczh 我只是想知道问题出在哪里? 如果把生产者和消费者写到一个类里面就可以正常工作。 分成两个类就不工作了?

@kylind 我是想说好歹检查下this。。。

@reverland 对的,我昨天找到了原因。 在对象初化的时候要添加对this的引用。 因为生产者与消费都方法都是被当作事件handler来传递。 等到调用的时候this已经变化了

@kylind 嗯。。。可以试试=>

回到顶部