【问题标题】:node.js redis asynchronous nature is confusingnode.js redis 异步性质比较混乱
【发布时间】:2016-02-22 17:05:18
【问题描述】:

我正在使用如下的 redis,但因为 on('message') 似乎被异步调用而遇到问题?

var subscriber = redis.createClient(port, host);
subscriber.subscribe('something');

subscriber.on('message', function(channel, message) {
    console.log('got message');

    // I use generator here

    var generator = myGenerator();
    var waitFunciton = generator.next().value;

    waitFunction(function(err, data) {

        var result = generator.next().value;

        // do something with result
        console.log('returning result');
    });

});

我希望看到

'got message'  
'returning result'
'got message'  
'returning result'

按顺序。

有时我会看到以下内容

'got message'
'got message'
'returning result'

看到缺少的“返回结果”,程序卡住了。

我应该如何修复程序?

** 编辑 **

var myGenerator = function* (arg) {
    main = {};
    main.messenger = new Backbone.Model();

    // performs something heavy

    // at the end of the heavy work,
    // main.messenger.trigger('done') is called

    _.extend(main, {
        wait: function (callback) {
            return main.messenger.once('done', callback);

        }
    });

    yield _.bind(main.wait, main);

    // since I have results at hand I'm returning result next time when I'm called

    var result;

    return result;

}

【问题讨论】:

  • myGenerator 函数有什么作用?你能发布它的代码吗?
  • 我添加了生成器代码
  • 哦,在抽象出代码时打错了。
  • 什么是waitFunction?它似乎负责不解雇第二个returning result
  • waitFunction 是 myGenerator 产生的 main.wait

标签: javascript node.js redis


【解决方案1】:

您的代码卡住了,因为您在第一次调用 myGenerator 后只触发了一次 donenext() 调用不会使生成器函数从一开始就执行,因此 callbacklog('returning result') 只执行一次。

您可以修改您的main.wait 函数以检查您的繁重计算是否已经完成并立即调用回调。

var myGenerator = function* (arg) {
    main = {};
    main.messenger = new Backbone.Model();

    // performs something heavy

    // at the end of the heavy work,
    // main.messenger.trigger('done') is called
    // main.messenger.set('computationDone', true);

    _.extend(main, {
        wait: function (callback) {
            if (main.messenger.get('computationDone') === true){
                 callback(); //filled with some data of course
            } else {
                return main.messenger.once('done', callback);
            }
        }
    });

    yield _.bind(main.wait, main);

    // since I have results at hand I'm returning result next time when I'm called

    var result;

    return result;
}

【讨论】:

    猜你喜欢
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    • 2020-09-14
    • 1970-01-01
    • 2014-04-24
    • 1970-01-01
    • 2013-03-25
    相关资源
    最近更新 更多