等待承诺在阵列中解决 [英] Waiting for Promises to resolve within an Array

查看:47
本文介绍了等待承诺在阵列中解决的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

具有承诺数组,我如何等到它们全部解决后再继续?

With an Array of Promises how do I wait until they have all resolved before proceeding?

下面是一个示例实现,其中 task_2 task_1 触发之前触发了拒绝。

Below is an example implementation, where task_2 is firing it's rejection before task_1 can trigger.

const $output = $$('output')

const config = {
  task_1: [
    val => new Promise((resolve, reject) => setTimeout(() => reject('Awaited error'), 2000)),
    val => new Promise((resolve, reject) => resolve(val))
  ],
  task_2: [
    val => new Promise((resolve, reject) => resolve(val)),
    val => new Promise((resolve, reject) => reject('An error')),
  ]
}

taskRunner({
    task_1: 'task parameters',
    task_2: 'task parameters'
  })
  .then(res => $output.text(res).fadeIn())
  .catch(err => $output.text(err).fadeIn())

function taskRunner(tasks) {
  return new Promise((resolve, reject) => {
    let arr = []
    for (const task in tasks) {
      if (!config.hasOwnProperty(task)) return reject(`${task} has no tasks`)
      arr.push(config[task].map((cb => cb(tasks[task]))))
    }

    const toRun = arr.reduce((a, b) => a.concat(b))
    Promise.all(toRun)
      .then(res => resolve(res))
      .catch(err => reject(err))
  })
}

function $$(data) {
  return $('[data-' + data + ']')
}

html, body { margin: 0; padding: 0 }
div.output {
  font-family: 'Courier', monospace;
  color: #383838;
  margin: 15px;
  padding: 15px 20px;
  background: #fafafa;
  border-radius: 3px;
  border-bottom: 1px solid #dadada;
}
.js-hide { display: none }

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="output js-hide" data-output></div>

推荐答案

如果我正确理解了您的问题,我想您可能仍会使用 Promise.all(),但是您必须兑现承诺通过功能分别处理拒绝。我的意思是,您可能会在拒绝被触发之前触发 Promise.all()并通过使用特殊对象解决拒绝来处理拒绝。

If i understand your problem correctly i guess you might still use Promise.all() however you have to wrap your promises by a function to handle the rejections separately. I mean you may catch the rejection before it triggers a premature exit of the Promise.all() and handle the rejection by resolving it with a special object.

例如;

As an example;

function handleRejectedPromises(p){
  return new Promise((resolve,reject) => p.then(v => resolve({status: "resolved", value: v}))
                                          .catch(x => resolve({status: "rejected", reason: x})));
}
var ps = [Promise.resolve(42), Promise.reject(37), Promise.resolve(23), Promise.resolve(11)];

Promise.all(ps.map(p => handleRejectedPromises(p)))
       .then(ra => ra.forEach(r => console.log(r)));


按照@Bergi的评论,我必须相应地更正我的答案,才能脱离反模式领域。

OK as per @Bergi's comment i have to correct my answer accordingly in order to take it off of anti-pattern realm.

function handleRejectedPromises(p){
  return p.then(v => ({status: "resolved", value: v}))
          .catch(x => ({status: "rejected", reason: x}));
}
var ps = [Promise.resolve(42), Promise.reject(37), Promise.resolve(23), Promise.resolve(11)];

Promise.all(ps.map(p => handleRejectedPromises(p)))
       .then(ra => ra.forEach(r => console.log(r)));

这篇关于等待承诺在阵列中解决的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆