【问题标题】:How to check if Javascript Promise has been fulfilled?如何检查 Javascript Promise 是否已实现?
【发布时间】:2018-06-17 01:33:31
【问题描述】:

我通过添加循环和延迟对象对example 进行了一些修改,以了解所有承诺都已实现。

我想要做的是将所有承诺推入一个数组,并在所有承诺都完成后将它们打印出来。

这是我的代码:

get_data();

function get_data() {


  var myPromise = [];
  var calls = [];
  var resultset = '';
  for (var j = 0, k = 5; j < k; j++) {
    var d = $.Deferred();
    var p = get_result();
    if (p.isPending()) {
      console.log('pending');
    }
    p.then(function(resultset) {
      if (p.isFulfilled()) {
        myPromise.push(resultset);
        calls.push(d);
      }
    });

  }

  $.when.apply($, calls).then(function() {
    console.log(myPromise); // always prints an empty array.
  });
}

function get_result() {

  return MakeQuerablePromise(new Promise(function(result, reject) {
    setTimeout(function() {
      result("Yeah !");
    }, 10000);
  }));
}

Fiddle获取完整代码

【问题讨论】:

  • Promise.all 似乎是你真正想要的,而不是使用 jquery almost 承诺 kludge 称为 Deferred
  • @JaromandaX 你能发布一个例子吗?谢谢
  • 不是真的因为我无法理解您的代码根本 - 我刚刚拿起你所说的等待所有承诺解决 -这听起来非常适合Promise.all - 每个人都可以使用其文档developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

标签: javascript jquery es6-promise jquery-deferred


【解决方案1】:

来自MDN

Promise.all(iterable) 方法返回单个 Promise,当可迭代参数中的所有承诺都已解决或可迭代参数不包含任何承诺时,该 Promise 将解决。它以第一个拒绝的承诺的原因拒绝。

var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
   setTimeout(resolve, 100, 'foo');
}); 

Promise.all([p1, p2, p3]).then(values => { 
  console.log(values); // [3, 1337, "foo"] 
});

【讨论】:

    【解决方案2】:

    您的代码的问题是您在每个延迟完成后填充calls 数组。这意味着当您运行 $.when.apply($, calls) 时,calls 仍然是空的,因此由于没有未完成的延迟,它会在任何调用实际完成之前立即解决。

    您的代码也不必要地令人费解。正如已经建议的那样,使用 Promise 接口和Promise.all() 可以获得很多好处。在你的情况下,我会做这样的事情:

    function get_data() {
    
    
      var calls = [];
      for (var j = 0, k = 5; j < k; j++) {
        calls.push(get_result());
      }
    
      Promise.all(calls).then(function(results) {
        console.log(results); // results is an array containing the result from each call.
      });
    }
    

    无需检查承诺是否已解决,一旦解决,将调用 then 回调。如果一个 Promise 被拒绝,这应该通过在 Promise 链中的某处使用 catch 回调来处理。这是一个承诺仅有的两种可能结果。


    附:您的代码的另一个问题是,您总是将循环中创建的最后一个 deferred 推送到 calls 数组。这是因为d 的范围在 for 循环之外,然后在每次迭代中重新分配,当异步调用解决时,它已经被分配了最终的 deferred。

    【讨论】:

    • 谢谢米凯尔。只有一个问题:这适用于 ajax 吗?
    • 请注意,Promise 对象对 IE 不友好
    • @Snappy 这取决于 AJAX 实现,但通常是的,几乎所有现代 AJAX 库/框架都支持承诺
    • @PhilLucks 是的,但话说回来,什么是? ;) ...我建议为此使用 polyfill,而不是使用 jQuery 的怪异延迟。
    猜你喜欢
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-06
    • 2015-01-15
    • 2011-10-14
    相关资源
    最近更新 更多