Search code examples
javascriptjqueryes6-promisejquery-deferred

How to check if Javascript Promise has been fulfilled?


I have modified this example a little by adding loop and Deferred object to know all promise have been fulfilled.

What I want to do is to push all promise into an array and print them out when all are fulfilled.

Here is my code:

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 for complete code


Solution

  • The problem with your code is that you populate the calls array after each deferred has fulfilled. This means that calls is still empty when you run $.when.apply($, calls), and thus since there are no unfulfilled deferreds it will resolve immediately, before any of the calls has actually fulfilled.

    Your code is also needlessly convoluted. As has been suggested, you have much to gain from using the Promise interface and Promise.all(). In your case, I would do something like this:

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

    There's no need to check if a promise has resolved, the then callback will be invoked once it resolves. If a promise instead gets rejected, this should be handled by using a catch callback somewhere in the promise chain. And those are the only two possible outcomes of a promise.


    P.S. A separate issue with your code is that you always push the last deferred created in the loop to the calls array. This is because d is scoped outside of the for loop and, then reassigned in each iteration and by the time the asynchronous calls resolve it has already been assigned the final deferred.