我很难理解如何处理需要一起解决的承诺组。
在我的情况下,我希望根据ids数组进行一系列promise调用,并有选择地将它们添加到输出数组中。如果这是PHP,我会这样做:
$output = []
foreach($input as $id) {
$result1 = functioncall1($id);
$result2 = functioncall2($result1);
if ($result2 == 'some filter') {
$output[] = $result1;
}
}这不能通过异步调用来完成,因为循环不会等待结果返回。所以我对蓝鸟使用了如下的promises:
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) {});
}我显然遗漏了一些东西,因为我的输出只包含一个未定义的数组。然而,它显然是映射并到达最终的,然后当我期望它的时候,那些未定义的数组只在过滤oks它时产生。即使筛选器只返回文字字符串,也会生成未定义的。
我正在清理遗漏的东西,但我正在努力填补这些空白。
发布于 2017-09-13 19:47:46
我以为这上面已经有答案了,但显然没有(或者如果它找到了,几次快速搜索也没有找到它)。
你想要一个这样的结构:
let filteredResults = Promise.all(arr.map(x => promisifiedFn1(x)))
.then(xs => xs.map(result1 => promisifiedFn2(result1)))
.then(ys => ys.filter(someFilteringFn));Promise.all可以被认为是颠倒了一个容器:您给它一个Promise数组(通过将Promise返回函数映射到一个输入数组上),它给您一个结果数组的Promise,然后您可以像对待任何其他数组一样对待它。
因此,xs是第一个函数的结果数组,一旦它全部解析,就会映射到输入上。ys是第二个。我不确定bluebird的Promise.map是做什么的,但您可以将我代码中的前两个步骤与它结合起来。
因为您在决定是否保留结果之前对每个输入进行了完整的处理,所以简单地使用两个异步步骤处理输入,然后在所有问题都解决后过滤结果数组不会有任何损失。
发布于 2017-09-13 20:04:20
确保你的promisified函数是正确的,这也应该是可行的:
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>
Promise.map允许您将任何数组映射到promise数组中,并生成一个新的promise,一旦所有这些promise都被解析,该promise将被解析。在映射函数中,您可以将两个promises链接在一起。
发布于 2017-09-13 20:35:28
你可以减少eta,让代码看起来更简单:
Promise.map(input, promisifedFunction1)
.map(promisifiedFunction2)
.filter(v => v === 'someFilter')
.then(outputFunction);https://stackoverflow.com/questions/46195985
复制相似问题