Node.js Api在Async循环中调用

我很难做出多个API调用,并得到正确的地方返回的结果。 这是我想要实现的:两个循环,嵌套。 外层循环遍历复杂的json对象,并将一些对象的值放入数组调用框中。 内部循环调用api,并将返回的结果放入一个名为bag的数组中。 所以我有箱子和袋子充满数据。 当循环和API呼叫都结束时,我想要访问箱子和包里的数据,然后用它做东西。 我只是不确定最好的方法去同时访问两个数组。 这是我到目前为止,但袋和框当然是空的,因为它们在所有循环和API调用结束之前被调用。

var data = {}//a json object with data; var bag = []; var box = []; async.forEach(data.item, function(item, callback){ async.forEach(item.name, function(name, callback){ callApi(item.name, function(obj){ bag.push(obj); }); callback(); } box.push(item); callback(); }); function callApi(name, callback){ asyncApiCall(url+name, function(err, result){ callback(result); }); } //when all loops and api requests are done //do stuff with contents of box and bag here; console.log(bag, box); 

您可以使用计数器确保所有asynchronous调用已经返回,然后调用callback。 一个例子:

 function performAsyncOperation(data, onCompletion) { var bag = []; var box = []; var count = 0; async.forEach(data.item, function(item, callback){ async.forEach(item.name, function(name, callback){ count += 1; callApi(item.name, function(obj){ bag.push(obj); count -= 1; if (count == 0) { onCompletion(null, { bag:bag, box:box }); } }); callback(); } box.push(item); callback(); }); } 

countonCompletion是上面的重要部分。

由于您拥有完整的数据集,因此您应该首先(同步)将名称列表集中到一个数组中。

那么,只能做一个async.forEach级别。 试图用两个级别来做到这一点是不必要的,并导致更复杂的代码。

如果你所说的async是你使用npm install async得到的,那么这里有一段代码说明你可以使用什么(使用lodash来build立名字列表,因为这往往会更加简洁。

 var _ = require("lodash"); var async = require("async"); var data = { item: [ {name: "a"}, {name: "b"} ] }; var bag = []; var items = _(_(data.item).collect(function(item) { return item.name; })).value(); async.eachSeries(items, function(name, cb) { callApi(name, function(obj) { bag.push(obj); cb(); }); }, function done() { console.log("bag", bag); }); function callApi(name, cb) { cb(name); } 

输出是:

 bag [ 'a', 'b' ]