在arrays上推送相同的函数时调用asynchronous函数

我有这个代码:

var queue = []; var allParserd = []; _.each(webs, function (web) { queue.push(function () { WebsitesUtils.parseWebsite(web, function (err, parsed) { allParserd.push(parsed); }); }); }); Promise.all(queue).then(function (data) { console.log(allParserd); }); 

基本上我需要抓取我所有的网页,并确保在完成每个parsing之后给出结果。 函数parseWebsite返回正确的数据,但是这样不被调用, allParsed只返回一个空数组。 我相信我错过了一些事情,我已经开始使用诺言了,只是有些日子。

如果您需要更多信息,请告诉我。

Ps我想要所有的function同时启动; 我不想等待每一个回应。

       

网上收集的解决方案 "在arrays上推送相同的函数时调用asynchronous函数"

Promise.all不需要执行一个函数队列。 它期望一系列的承诺 ,代表许多并发运行(仍然未决)的请求的结果。

第一步是有一个函数实际返回一个promise,而不是只执行一个callback。 我们可以用

 function parseWebsite(web) { return new Promise(function(fulfill, reject) { WebsitesUtils.parseWebsite(web, function (err, parsed) { if (err) reject(err); else fulfill(parsed); }); }); } 

或者简单地使用这样做的promisification :

 var parseWebsite = Promise.promisify(WebsitesUtils.parseWebsite, WebsitesUtils); 

现在我们可以通过为每个站点调用该函数来构造我们的承诺数组:

 var promises = []; _.each(webs, function (web) { promises.push(parseWebsite(web)); }); 

要不就

 var promises = _.map(webs, parseWebsite); 

所以最后我们可以使用Promise.all ,并返回我们的allParsed数组(甚至与webs顺序相同):

 Promise.all(promises).then(function(allParsed) { console.log(allParsed); }); 

蓝鸟甚至提供了一个快捷function,所以你不需要promises

 Promise.map(webs, parseWebsite).then(function(allParsed) { console.log(allParsed); }); 

标签为蓝鸟,让我们使用它:

首先,我们将您的callbackAPI转换为承诺:

  Promise.promisifyAll(WebsitesUtils); 

现在,让我们使用.map将web中的每个项目映射到被parsing的parseWebsite:

 Promise.map(webs, function(item){ return WebsitesUtils.parseWebsiteAsync(item); // note the suffix }).then(function(results){ // all the results are here. }).catch(function(err){ // handle any errors }); 

正如你所看到的 – 这对Bluebird来说是微不足道的。

下面是如何做到这一点与async

 var async = require('async'); var webs = ... async.map(webs, function(web, callback) { WebsitesUtils.parseWebsite(web, callback); }, function(err, results) { if (err) throw err; // TODO: handle errors better // `results` contains all parsed results }); 

如果parseWebsite()不是依赖于WebsitesUtils的原型方法,那么您可以进一步简化它:

 async.map(webs, WebsitesUtils.parseWebsite, function(err, results) { if (err) throw err; // TODO: handle errors better // `results` contains all parsed results });