我有一个URL数组,我想循环遍历它们并获取thr内容。在我循环遍历它们并获取thr内容之后,我希望调用一个回调函数。
我知道我可以通过异步库来做到这一点,但我想在不使用任何库的情况下这样做。 我想要的代码示例如下
['yahoo.com', 'gmail.com'].each(function(item){
//code to fetch URL content
},someCallbackFunctionToBeExecutedAtTheEndOfLoop);
答案 0 :(得分:2)
这通常是你使用promises做的事情(但你需要一个库),代码如下:
var ops = [];
urls.forEach(function(url) {
ops.push(fetchUrl(url));
});
P.all(ops).then(callback);
function fetchUrl(url) {
var defer = P.defer();
//do stuff
// call defer.resolve(result);
return defer.promise;
}
如果您不想使用承诺,可以使用操作计数器,例如:
var ops = urls.length;
urls.forEach(function(url) {
// do stuff
ops--;
if (ops === 0) {
callback();
}
});
如果您选择了承诺,我建议使用p-promise模块,它比Q更加优化。
答案 1 :(得分:1)
如果你想在没有像async这样的库的情况下这样做,那么你必须编写自己的计数器来跟踪所有异步响应何时完成:
var request = require('request');
function loadAll(list, fn) {
var cnt = list.length;
var responses = [];
list.forEach(function(url, index) {
request(url, function(error, response, body) {
if (error) {
fn(error);
} else {
responses[index] = response;
--cnt;
if (cnt === 0) {
fn(0, responses);
}
}
});
})
}
loadAll(['http://www.yahoo.com', 'http://www.gmail.com'], function(err, results) {
if (!err) {
// process results array here
}
});
如果您要在node.js中执行许多异步操作,那么获取像Bluebird这样的承诺库将为您节省大量时间。例如,我认为你可以在这样的事情中做到这一点(未经测试):
var Promise = require("bluebird");
var requestP = Promise.promisfy(require("request"));
Promise.map(['http://www.yahoo.com', 'http://www.gmail.com'], requestP).then(function(results) {
// process the array of results here
});