首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用promises组

使用promises组
EN

Stack Overflow用户
提问于 2017-09-13 19:11:10
回答 4查看 409关注 0票数 1

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

在我的情况下,我希望根据ids数组进行一系列promise调用,并有选择地将它们添加到输出数组中。如果这是PHP,我会这样做:

代码语言:javascript
复制
$output = []
foreach($input as $id) {

  $result1 = functioncall1($id);
  $result2 = functioncall2($result1);

  if ($result2 == 'some filter') {
    $output[] = $result1;
  }
}

这不能通过异步调用来完成,因为循环不会等待结果返回。所以我对蓝鸟使用了如下的promises:

代码语言:javascript
复制
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它时产生。即使筛选器只返回文字字符串,也会生成未定义的。

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

EN

回答 4

Stack Overflow用户

发布于 2017-09-13 19:47:46

我以为这上面已经有答案了,但显然没有(或者如果它找到了,几次快速搜索也没有找到它)。

你想要一个这样的结构:

代码语言:javascript
复制
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是做什么的,但您可以将我代码中的前两个步骤与它结合起来。

因为您在决定是否保留结果之前对每个输入进行了完整的处理,所以简单地使用两个异步步骤处理输入,然后在所有问题都解决后过滤结果数组不会有任何损失。

票数 1
EN

Stack Overflow用户

发布于 2017-09-13 20:04:20

确保你的promisified函数是正确的,这也应该是可行的:

代码语言:javascript
复制
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!";
  })
代码语言:javascript
复制
<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链接在一起。

票数 1
EN

Stack Overflow用户

发布于 2017-09-13 20:35:28

你可以减少eta,让代码看起来更简单:

代码语言:javascript
复制
Promise.map(input, promisifedFunction1)
       .map(promisifiedFunction2)
       .filter(v => v === 'someFilter')
       .then(outputFunction);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46195985

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档