多个Async系列在Javascript中导致错误行为

时间:2014-02-14 09:47:36

标签: javascript asynchronous

我正在使用异步库(浏览器版本)。当我将异步调用嵌入到另一个内部时,我发现async series的正常(读取'预期')行为失败了。

以下是一些产生错误输出的小提琴

fiddle 1

fiddle 2

这里总结了问题

使用以下代码

$(function(){

async.series([

function f1(cb) {
    setTimeout(function () {
        console.log("Hello from f1");
        cb(null);
    }, 3000);

    async.series([

    function f11(cb) {
        setTimeout(function () {
            console.log("Hello from f11");
            cb(null);
        }, 3000);
    }, function f12(cb) {
        setTimeout(function () {
            console.log("Hello from f12");
            cb(null);
        }, 3000);
    }, function f13(cb) {
        setTimeout(function () {
            console.log("Hello from f13");
            cb(null);
        }, 3000);
    }], function (err, res) {
        console.log("Done all in f1");
    });

}, function f2(cb) {
    setTimeout(function () {
        console.log("Hello from f2");
        cb(null);
    }, 3000);
}],

function (err, res) {
    console.log("Done all");
});

});

我预计输出如下

Hello from f1 
Hello from f11
Hello from f12
Hello from f13
Done all in f1
Hello from f2 
Done all

但我得到了这个 -

Hello from f1
Hello from f11
Hello from f2
Done all 
Hello from f12
Hello from f13 
Done all in f1

我看到问题了吗?我认为async.series因为同时运行多个异步系列而感到困惑。如果是这种情况,我如何将嵌套的管道插入主管道中。任何人帮助@Caolan

来自@tom的EDIT答案。在下面的代码更正代码

中提前调用cb(null)是错误的
$(function () {

async.series([

function f1(cb) {
    setTimeout(function () {
        console.log("Hello from f1");
    }, 3000);

    async.series([

    function f11(cb1) {
        setTimeout(function () {
            console.log("Hello from f11");
            cb1(null);
        }, 3000);
    }, function f12(cb1) {
        setTimeout(function () {
            console.log("Hello from f12");
            cb1(null);
        }, 3000);
    }, function f13(cb1) {
        setTimeout(function () {
            console.log("Hello from f13");
            cb1(null);
        }, 3000);
    }], function (err, res) {
        console.log("Done all in f1");
        cb(null);
    });

}, function f2(cb) {
    setTimeout(function () {
        console.log("Hello from f2");
        cb(null);
    }, 3000);
}],

function (err, res) {
    console.log("Done all");
});

});

2 个答案:

答案 0 :(得分:1)

对于异步函数,调用回调类似于从正常函数返回,因为它恢复执行程序的其余部分。在函数f1中,调用cb会导致执行f2(最终会打印Hello from f2Done all)。

为确保在f2之后执行f11f12f13全部完成,对cb的调用应移至最终回调在行async.series()之后调用内部console.log("Done all in f1")

答案 1 :(得分:0)

来自@tom的EDIT答案。在代码的早期调用cb(null)是错误的 - 在问题本身上面编辑了纠正的代码。