我很难理解如何与需要共同解决的承诺小组合作。
在我的情况下,我想基于一组id进行一系列的promise调用,并有选择地将它们添加到输出数组中。如果这是PHP,我会做类似的事情:
$output = []
foreach($input as $id) {
$result1 = functioncall1($id);
$result2 = functioncall2($result1);
if ($result2 == 'some filter') {
$output[] = $result1;
}
}
这不能通过异步调用来完成,因为循环不会等待返回结果。所以我正在使用蓝鸟这样的承诺:
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) {});
}
我在这里显然遗漏了一些东西,因为我的输出只包含一个未定义的数组。然而,当我期望它时,它显然是映射并到达最终,并且那些未定义的数组仅在过滤时产生。即使过滤器只返回一个文字字符串,也会生成undefined。
我正在清除遗漏的东西,但我正在努力填补空白。
答案 0 :(得分:1)
我认为这已经在SO上有了答案,但显然它没有(或者如果它做了几次快速搜索并没有找到它)。
你想要一个像这样的结构:
let filteredResults = Promise.all(arr.map(x => promisifiedFn1(x)))
.then(xs => xs.map(result1 => promisifiedFn2(result1)))
.then(ys => ys.filter(someFilteringFn));
Promise.all
可以被认为是将一个容器从里面翻出来:你给它一个Promises数组(通过在一个输入数组上映射你的promise-returns函数),它给你一个数组的Promise然后你像任何其他数组一样处理的结果。
所以xs
是一旦它全部解析就映射到输入上的第一个函数的结果数组。 ys
是第二个。我不确定蓝鸟的Promise.map
是做什么的,但您可以将我的代码中的前两个步骤与它结合起来。
由于在决定是否保留结果之前对每个输入进行了全面处理,因此只需处理两个异步步骤的输入,然后在一切结算后过滤生成的数组就不会受到惩罚。 / p>
答案 1 :(得分:1)
确保您的宣传功能正常,这也应该有效:
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
允许您将任何数组映射到promises数组中,并生成一个新的promise,一旦解决了所有这些promise,就会解析它。在映射函数中,您可以链接两个promise。
答案 2 :(得分:1)
你可以进行eta-reduction以使代码看起来更简单:
Promise.map(input, promisifedFunction1)
.map(promisifiedFunction2)
.filter(v => v === 'someFilter')
.then(outputFunction);
答案 3 :(得分:0)
您可以使用 Promise.all
var promise1 = new Promise(function (resolve, reject) {
// promise1 code here
resolve(true);
})
var promise2 = new Promise(function (resolve, reject) {
// promise2 code here
resolve(true);
})
var promise3 = new Promise(function (resolve, reject) {
// promise3 code here
resolve(true);
})
这里我们使用了 3 个 Promise,现在如果我们必须在解决所有 Promise 后执行代码,我们可以使用 Promise.all
Promise.all([promise1, promise2, promise3]).then(() => {
// code
});