如果其中一个失败,Promise.all不会返回任何承诺

时间:2018-03-28 15:14:34

标签: javascript promise es6-promise

我发布了question earlier about Promise.all和d3.js v5,但是关于这段代码又出现了另一个问题:

var files = ["data1.json", "data2.json", "data3.json"];
var promises = [];

files.forEach(function(url) {
    promises.push(d3.json(url))
});

Promise.all(promises).then(function(values) {
    console.log(values)
});

如果其中一个URL无效,则Promise.all不会返回任何结果;换句话说,所有响应必须对Promise.all有效才能返回值。如果其中一个URL出现错误,如何获得其他响应?

5 个答案:

答案 0 :(得分:2)

这就是Promise.all的工作方式。但是如果你想让它被拒绝承诺,你可以这样做:

var files = ["data1.json", "data2.json", "data3.json"];
var promises = [];

files.forEach(function(url) {
    promises.push(
      d3.json(url)
        .then(function(data) {
          return {success: true, data: data};
        }, function() {
          return {success: false};
        })
    )
});

Promise.all(promises).then(function(values) {
    console.log(values)
});

请注意Promise#then可以接受两个函数作为参数,第一个函数在解析promise时被调用,第二个函数在被拒绝时被调用。

您可以手动解决被拒绝的承诺,并可以返回一个标识符,以了解该呼叫是成功还是失败,就像我使用success密钥一样。

答案 1 :(得分:1)

尝试将每个承诺包装到您的自定义承诺中并解决每个承诺。





以下是示例:

&#xA;&#xA; < pre> const wrappedPromises = promises.map(promise =&gt; {&#xA; if(promise){&#xA; return new Promise((resolve,reject)=&gt; {&#xA; promise.then (解析).catch(resolve);&#xA;});&#xA;}&#xA;});&#xA;&#xA; Promise.all(wrappedPromises).then(function(values){ &#xA; console.log(values)&#xA;});&#xA; &#xA;

答案 2 :(得分:1)

你想要像Promise.settle这样的东西。您可以使用Bluebird和.reflect()http://bluebirdjs.com/docs/api/reflect.html

&#13;
&#13;
function settle (promises) {
  return Promise.all(promises.map(promise => promise.reflect()));
}


var x = [Promise.resolve(1), Promise.reject(new Error("omg")), Promise.resolve(2)];

settle(x).then(console.log)
&#13;
<script src="//cdn.jsdelivr.net/bluebird/3.5.0/bluebird.js"></script>
&#13;
&#13;
&#13;

答案 3 :(得分:1)

使用Promise.all,您需要确保每个Promise都会解析(意味着它不会拒绝)。它很容易实现这一点,只需处理拒绝并从中恢复。例如:

var files = ["data1.json", "data2.json", "data3.json"];
var promises = files.map(function(url) {
  return d3.json(url)
    .catch(function (err) {
      return {
        error: err
      }
    })
});

Promise.all(promises).then(function(values) {
  console.log(values)
});

所以你需要添加的是catch块:

.catch(function (err) {
  return {
    error: err
  }
}

答案 4 :(得分:0)

编写您自己的Promise.all版本。跟踪已解决和被拒绝的承诺,并在所有承诺得到解决或拒绝后返回您认为合适的数组。