解决 * 和 * 拒绝 Bluebird 中的所有承诺

Resolve *and* reject all promises in Bluebird

我正在寻找从 promise 数组中同时获得解决和拒绝的方法。我目前指望 Bluebird 实现,因此 ES6 兼容解决方案也适用。

我想到的最好的办法是使用 Bluebird 的 Promise.settle,我认为这里的承诺检查是不必要的并发症:

  let promises = [
    Promise.resolve('resolved'),
    Promise.resolve('resolved'),
    Promise.reject('rejected')
  ];

  // is there an existing way to do this?
  let resolvedAndRejected = Promise.settle(promises)
  .then((inspections) => {
    let resolved = [];
    let rejected = [];

    inspections.forEach((inspection) => {
      if (inspection.isFulfilled())
        resolved.push(inspection.value());
      else if (inspection.isRejected())
        rejected.push(inspection.reason());
    });

    return [resolved, rejected];
  });

  resolvedAndRejected.spread((resolved, rejected) => {
    console.log(...resolved);
    console.error(...rejected);
  });

对于 100% 的履行率不是一个选项或目标的情况来说,这看起来像是一项微不足道的任务,但我什至不知道食谱的名称。

在 Bluebird 或其他 promise 实现中是否有一种简洁且经过充分验证的方法来处理此问题 - 内置运算符或扩展?

它没有内置任何内容,但reduce 可以使它非常简洁:

Promise
  .settle(promises)
  .reduce(([resolved, rejected], inspection) => {
    if (inspection.isFulfilled())
      resolved.push(inspection.value());
    else
      rejected.push(inspection.reason());
    return [resolved, rejected];
  }, [[], []]);

您可以使用 Promise.all()、处理被拒绝的 Promisereturn reason 或其他值来链接 .then()

let promises = [
  Promise.resolve("resolved"),
  Promise.resolve("resolved"),
  Promise.reject("rejected")
]
, results = {resolved:[], rejected:[]}

, resolvedAndRejected = Promise.all(
  promises.map((p) => {
    return p.then((resolvedValue) => {
      results.resolved.push(resolvedValue);
      return resolvedValue
    }, (rejectedReason) => {
      results.rejected.push(rejectedReason);
      return rejectedReason
    })
  }));

resolvedAndRejected.then((data) => {
  console.log(data, results)
});

自 OP 询问以来,为完整性添加了答案。这是我要做的:

 const res = Promise.all(promises.map(p => p.reflect())) // get promises
   .then(values => [
          values.filter(x => x.isFulfilled()).map(x => x.value()), // resolved
          values.filter(x => x.isRejected()).map(x => x.reason()) // rejected
   ]);