我正在使用异步的第三方api方法。我有需要传递给这个异步方法的项目列表,并且我希望在完成所有异步调用后打印出所有返回结果的结果。我知道我可以使用回调来实现这一目标。但我无法让它发挥作用。它什么都不打印。显然我在这里使用回调错了。是的,我在这里阅读了回调:https://github.com/maxogden/art-of-node#callbacks。有很好的例子。但不确定如何使它与异步调用数组一起使用并组合结果。
var resultArray = [];
var items = ["one", "two", "three"];
getResult(items, printResult);
function printResult()
{
for(let j=0; j < resultArray.length; j++)
{
console.log(resultArray[j]);
}
}
function getResult(items, callback)
{
for(let i=0; i<items.length; i++)
{
apiClient.findItem(items[i], function (error, item){
resultArray.push(item.key);
});
}
}
答案 0 :(得分:3)
正如@JeffreyAGochin指出的那样,你可以用promises代替它。如果您不想这样做并且想要坚持回调(我不建议这样做),您可以使用优秀的async。
function getResult(item, done) {
apiClient.findItem(item, done);
}
async.each(items, getResult, function (error, results) {
// if error is null, then all of your results are in 'results'
if(error !== null) throw error;
results.forEach(function(result) {
console.log(result);
});
});
示例承诺实现(我假设您正在使用ES6,因此由于您的let
原因而拥有Promise)
// When you are using promises natively (apparently these have performance implications, see comments) your code looks like this:
function getResult(item) {
return new Promise(function(resolve, reject) {
apiClient.findItem(item, function(error, foundItem) {
if(error) return reject(error);
resolve(foundItem);
});
});
}
// If you use the excellent bluebird library though (which is pretty common actually), it looks more like this.
let apiClient = Bluebird.promisifyAll(apiClient);
function getResult(item) { return apiClient.getItemAsync(item); }
var resultsPromise = Promise.all(items.map(getResult));
resultsPromise.then(function(results) {
results.forEach(function(result) {
console.log(result);
});
});
至于为什么这么多人提出承诺的原因;这是因为他们的组成远远好得多。还有一些很棒的库支持承诺,例如highland(也是上面async
的同一作者),它将承诺视为第一类值。很难对待这样的回调,因为没有真正的方法来“传递它们”
答案 1 :(得分:1)
+1承诺。某些人更喜欢的另一个选项是async
模块:
var async = require('async');
async.each(
items,
function (item, cb) { apiClient.findItem(item, cb); },
function (err, resultArray) {
for (let j=0; j < resultArray.length; j++) {
console.log(resultArray[j]);
}
}
);
答案 2 :(得分:0)
我建议使用Promises库来管理所有异步请求。他们通常有一个all方法,等待所有的承诺完成。您可以在promises中包装其他异步库调用。
答案 3 :(得分:0)
在getResult
中,您没有调用callback
参数,因此在这种情况下肯定不会打印任何内容。
如果你坚持回调而不是承诺,尽管肆虐的观点战争是完全可以接受的,一个不错的npm包是Async。查看该库中的each
函数,它可能会执行您想要的操作。
答案 4 :(得分:0)
我认为这就是您所寻找的:http://howtonode.org/promises。
我建议您使用变量来计算已完成的请求,这样您就可以检查所有请求的完成时间并使用数组执行所需的操作。