Javascript 在数组上推送相同的函数时调用异步函数
我有以下代码:Javascript 在数组上推送相同的函数时调用异步函数,javascript,node.js,promise,bluebird,Javascript,Node.js,Promise,Bluebird,我有以下代码: var queue = []; var allParserd = []; _.each(webs, function (web) { queue.push(function () { WebsitesUtils.parseWebsite(web, function (err, parsed) { allParserd.push(parsed); }); }); }); Promise.all(queue)
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);
});
基本上,我需要获取我所有的网站,并确保在每次解析完成后给出结果。函数parseWebsite
返回正确的数据,但不以这种方式调用,allParsed
返回空数组。我肯定我错过了一些东西,我已经开始使用承诺只是从一些天
如果你需要更多的信息就告诉我
附言。
我希望所有功能同时启动;我不想等待每一个响应才能继续前进。以下是如何使用: 如果
parseWebsite()
不是依赖于WebsitesUtils
的原型方法,那么您可以进一步简化它:
async.map(webs, WebsitesUtils.parseWebsite, function(err, results) {
if (err) throw err; // TODO: handle errors better
// `results` contains all parsed results
});
用蓝知更鸟做标记,让我们使用它: 首先,让我们将回调API转换为承诺:
Promise.promisifyAll(WebsitesUtils);
现在,让我们使用.map
将网站中的每个项目映射到正在解析的网站:
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来说是微不足道的。不需要一个函数队列来执行。它需要一个承诺数组,表示许多并发运行(仍挂起)请求的结果
第一步是让函数实际返回承诺,而不是只执行回调。我们可以使用
function parseWebsite(web) {
return new Promise(function(fulfill, reject) {
WebsitesUtils.parseWebsite(web, function (err, parsed) {
if (err)
reject(err);
else
fulfill(parsed);
});
});
}
或者简单地使用一般性的:
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.map(webs, parseWebsite).then(function(allParsed) {
console.log(allParsed);
});
你的parseWebsite函数真的应该被重构以返回一个承诺,混合回调和承诺可能会令人困惑。一旦你做到了这一点,你就可以利用像蓝鸟这样的人提供的Promise.map/Promise.each函数等。你在使用什么
Promise
库?蓝鸟,我将添加一个tagHi mscdex,谢谢你的回复。第一个解决方案似乎不起作用,WebsitesUtils从未被调用(并且它也不会返回错误),我不能使用第二个解决方案,因为它依赖于WebsitesUtils。感谢您的有用解释,我缺少了我需要的承诺数组而不是函数数组的部分。非常感谢。谢谢你的回复,这个解决方案也有效,我将另一个方案标记为解决方案,只是因为还有一个通用示例,而不仅仅是蓝鸟。谢谢again@DannoEterno如果你想更多地了解Promission是如何工作的,请参见:)另外,如果Bergi的解决方案能够解决你的问题,请务必投票表决。Promise标签相对较小,Bergi(以及jfriend和esailija等其他标签注册商)越快获得金徽章,对我们越有利,因为他获得了更多的节制特权:)是的,我知道,但我在stackoverflow上没有声誉,无法放弃他应得的投票权。我一直潜伏着,不可能对我找到的每一个解决方案进行投票,因此:(
Promise.all(promises).then(function(allParsed) {
console.log(allParsed);
});
Promise.map(webs, parseWebsite).then(function(allParsed) {
console.log(allParsed);
});