在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同时启动; 我不想等待每一个回应。
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 });