与承诺组合作

我很难理解如何与需要一起解决的承诺组合作。

在我的情况下,我想做一系列基于ID数组的promise调用,并select性地将它们添加到输出数组中。 如果这是PHP我会做这样的事情:

$output = [] foreach($input as $id) { $result1 = functioncall1($id); $result2 = functioncall2($result1); if ($result2 == 'some filter') { $output[] = $result1; } } 

这不能用asynchronous调用完成,因为循环不等待结果返回。 所以我使用蓝鸟这样的承诺:

 Promise.map(input, function(id) { promisifedFunction1(id) .then(function(result1) { //process result1 some more promisifedFunction2(result1) .then(function(result2) { //process result2 some more if (result2 == 'some filter') { return result1; }); }); }) .then(function(output) {}); } 

我显然在这里丢失了一些东西,因为我的输出只包含一个未定义的数组。 然而,当我期望它和那些未定义的数组只是在过滤时才产生,显然是映射并达到最终的结果。 即使filter只是返回一个文字string,也会产生未定义的。

我正在清理遗漏的东西,但我正在努力填补空白。

我认为这将在这里有一个答案,但显然它不(或者如果它做了几个快速search没有find它)。

你想要一个像这样的结构:

 let filteredResults = Promise.all(arr.map(x => promisifiedFn1(x))) .then(xs => xs.map(result1 => promisifiedFn2(result1))) .then(ys => ys.filter(someFilteringFn)); 

Promise.all可以被认为是一个容器里面的内容:你给它一个Promises数组(通过映射你的承诺 – 返回一个input数组的函数),它给你一个结果数组的承诺,你然后像任何其他arrays一样对待。

所以xs是第一个函数映射到input的结果的数组,一旦全部解决。 ys是第二个。 我不确定是什么蓝鸟的Promise.map ,但你可以将我的代码中的前两个步骤结合起来。

由于在决定是否保留结果之前对每个input做了全面的处理,因此,只要用两个asynchronous步骤简单处理input,然后在解决所有结果时过滤结果数组,就不会有任何损失。

确保你的promisifiedfunction是好的,这也应该工作:

 var elements = ["one", "two", "three"] var container = document.querySelector('.results') function promisifiedFunc1(arrayElement) { return new Promise(function(resolve, reject) { setTimeout(function() { resolve('input to the next func ' + arrayElement) }, 1000) }) } function promisifiedFunc2(inputFromPreviousFunc) { return new Promise(function(resolve, reject) { container.innerHTML += "<br>" + inputFromPreviousFunc setTimeout(function() { resolve('some filter') }, 1000) }) } Promise.map(elements, function(one) { return promisifiedFunc1(one).then(promisifiedFunc2); }) .filter(function(res2) { return res2 === 'some filter'; }) .then(function(allResults) { console.log(allResults); container.innerHTML += "<br>All Done!"; }) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.5.0/bluebird.min.js"></script> <div class="results"></div> 

你可以做eta减less使代码看起来简单得多:

 Promise.map(input, promisifedFunction1) .map(promisifiedFunction2) .filter(v => v === 'someFilter') .then(outputFunction);