按顺序节点异步调用

时间:2015-07-17 21:10:03

标签: javascript node.js asynchronous

我有几个异步请求从网址中获取一些数据。我遇到的问题是我实际上想要延迟发送json响应,直到所有请求都回来。代码看起来像这样:

getFirstStuff(callback) //imagine this is async
{
    console.log('gettingFirstStuff');
    callback(stuff);
}

function getFurtherStuff(callback) //imagine this is async
{
    console.log('gettingFurtherStuff');
    callBack(thing);
}

function getStuff(callBack)
{

    getFirstStuff(function(stuff) // async
    {
        // stuff is an array of 3 items

        stuff = stuff.map(function(item) // map is synchronous
        {
            // For each item in stuff make another async request
            getFurtherStuff( function(thing) { // this is also async
                stuff.thing = thing;
            });

            return item;
        });

        callback(stuff); 
    });

}

router.get('/getstuff', function(req, res, next) {
    getStuff(function(stuff)
    {
       console.log('finished stuff');

       // RETURN RESPONSE AS JSON
       res.json(stuff);
    });
});

输出将是:

gettingFirstStuff
finished stuff
gettingFurtherStuff
gettingFurtherStuff
gettingFurtherStuff

但它应该是:

gettingFirstStuff
gettingFurtherStuff
gettingFurtherStuff
gettingFurtherStuff
finished stuff

我知道原因是getFurtherStuff是异步的,并且在getFurtherStuff异步调用返回结果之前将从map返回item。我的问题是,在调用最终回调'回调(东西)'之前,等待这些调用完成的标准方法是什么?

2 个答案:

答案 0 :(得分:3)

有很多方法可以解决这个问题。如果添加依赖项没有问题,asyncqueue等库可能是最佳选择。

没有外部库的最简单的选择就是计算异步作业并在完成后完成:

// assuming stuff is an array
var counter = 0;
var jobCount = stuff.length;

// wrap callback in one that checks the counter
var doneCallback = function() {
    if (counter >= jobCount) {
        // we're ready to go
        callback(stuff);
    }
};

// run jobs
stuff.map(function(item) {
    getFurtherStuff(item, function(itemThing) {
        // process async response
        stuff.thing = itemThing;
        // increment counter;
        counter++;
        // call the wrapped callback, which won't fire
        // until all jobs are complete
        doneCallback();
    });
});

答案 1 :(得分:0)

npm install async

然后,您只需将函数放入async.parallel()

即可

https://www.npmjs.com/package/async

的更多信息