after循环中的node.js回调函数已经结束

时间:2015-03-21 18:52:43

标签: node.js

我有一个URL数组,我想循环遍历它们并获取thr内容。在我循环遍历它们并获取thr内容之后,我希望调用一个回调函数。

我知道我可以通过异步库来做到这一点,但我想在不使用任何库的情况下这样做。 我想要的代码示例如下

['yahoo.com', 'gmail.com'].each(function(item){
//code to fetch URL content
},someCallbackFunctionToBeExecutedAtTheEndOfLoop);

2 个答案:

答案 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
});