等待Promise在数组内解析

时间:2016-12-21 14:36:04

标签: javascript arrays object asynchronous promise

使用承诺数组,如何在继续之前等待它们全部解决?

以下是一个示例实现,其中from django.test import Client c = Client() response = c.get('/mymodel/1') content = response.content task_2触发之前解除了它的拒绝。



task_1

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 }




2 个答案:

答案 0 :(得分:0)

如果我从您的评论中正确理解您的问题

这实际上只是一个例子,我很好奇你在继续之前如何等待一系列Promise 解决/拒绝。例如,你可能有一个Promises数组进行HTTP调用,如果发生错误,你可能希望输出所有错误而不是最新错误。

您要等到所有承诺都已解决或拒绝,然后继续。

myList = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 将拒绝数组中任何给定的promises被拒绝,因此在这种情况下它不是你的替代。

jQuery中有public string Something { get; set; } [DataType(Something.Contains("whatever") ? "whatever" : "notwhatever")] public double Price{ get; set; } 函数可以这样工作,如果你使用BlueBird,可以使用Promise.all()来检查.always()的承诺。 ES6中没有可以执行此操作的当前功能。

借用此问题的答案ES6 promise settled callback?,您可以像这样实施自己的.reflect() / Promise.all() / .always()版本

.finally()

答案 1 :(得分:0)

如果我理解你的问题,我猜你可能仍然使用Promise.all()但是你必须通过一个函数包装你的承诺来分别处理拒绝。我的意思是你可以在触发过早退出Promise.all()之前发现拒绝并通过用特殊对象解决它来处理拒绝。

作为一个例子;

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的评论,我必须相应地更正我的答案,以便将其从反模式领域中删除。

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)));