Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/441.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在数组上推送相同的函数时调用异步函数_Javascript_Node.js_Promise_Bluebird - Fatal编程技术网

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