node.js for循环中async.series的问题


尝试使用 https://github.com/caolan/async#series 来实现一些串行操作,不过出现了一个问题,请看代码:


 async.series({
    one: function(callback){
        setTimeout(function(){
            callback(null, 1);
            console.log("one");
        }, 2000);
    },
    two: function(callback){
        setTimeout(function(){
            callback(null, 2);
            console.log("two");
        }, 1000);
    }
},
function(err, results) {
    // results is now equal to: {one: 1, two: 2}
});

以上代码输出


 one
two

这没有问题。

但是在for循环中调用async.series


 for (var i = 0; i < 3; i++) {
    async.series({
        one: function(callback){
            setTimeout(function(){
                callback(null, 1);
                console.log("one");
            }, 2000);
        },
        two: function(callback){
            setTimeout(function(){
                callback(null, 2);
                console.log("two");
            }, 1000);
        }
    },
    function(err, results) {
        // results is now equal to: {one: 1, two: 2}
    });
}

个人的预期是输出


 one
two
one
two
one
two

但实际结果是:


 one
one
one
two
two
two

求解答。

环境


 Mac OS X 10.8.5
[email protected]
[email protected]

node.js async

Alien丿鸣 11 years, 3 months ago

虽然说如果熟悉 JavaScript 的异步机制,这是一个很好理解的原理,但我们尽量别看得这么复杂:

async.series 的作用是,先执行 one,完毕再执行 two,这个很好理解。

因此在 for 循环里你做了这么一件事:一口气创建三个「先执行 one,再执行 two」

于是,大家一起先执行 one,然后「不约而同」地执行 two。

所以就这样了。


这或许不是你想要的答案,但如果初次接触 JavaScript 的移步的话,建议还是先花时间理解回调的工作方式,而不是套用 async 这类把细节封装掉的库。

如果想深入理解的话,可以试试最原始的递归:


 var i = 0

function recurse () {
  // ...做爱做的事...
  i++
  if (i < 2) {
    recurse()
  }
}

recurse()

或者尝试朴灵大神的 EventProxy 库,「当『什么』发生时干『嘛』」的思路。

好像偏题了。。。

7758542 answered 11 years, 3 months ago

Your Answer