简体   繁体   中英

My promise is resolving before I think it should

I am trying to use q promises to handle some long-running ajax requests and subsequent data processing. I have a case where I am trying to create some promises that should be executed in sequence, but they seem to be resolving before I want them to and I'm not sure why.

The main sequence is to first try some "main" work which should be done asynchronously, then do some "follow-up" work which itself comprises a set of several async requests. Here's the main body from my fiddle which demos the problem:

var to_do = ["one", "two", "three", "four"];
var result = Q();
to_do.forEach(function (item) {
  result = result
    .then(dowork.bind(null, item))
    .fail(handleError)
    .then(dofollowup.bind(null, item));
});

var dowork = function (value) {
  var deferred = Q.defer();
  log("About to do main work for " + value);
  setTimeout(function () {
    if (value === 'two') {
      // represent a possible error in this work, but we still need to do follow-up work
      deferred.reject("An error occurred doing work for number two, but we should continue");
    } else {
      log("Done main work for " + value);
      deferred.resolve(value);    
    }
  }, 1000);
  return deferred.promise;
}

var dofollowup = function (value) {
  log("Doing follow-up work for " + value);
  var to_do = Q();
  for (var i=0; i<5; i++) {
    to_do = to_do.then(function () {
      var deferred = Q.defer();
      setTimeout(function () {
        log("Doing delayed work for " + value);
        deferred.resolve();
      }, 100);
    });
  }
  return to_do;
}

My immediate problem is that the "main" work for the next item is being started before the "follow-up" work for an item is finished. I am guessing I'm just not dealing with the promises correctly and accidentally resolving it too soon, but I don't see how at the moment.

I created a fiddle that simulates my problem. In it, I see the work for the "two" work item starting before the follow-up for "one" is complete. How can I insure that I complete each item's follow-up before starting on the main work for the next?

https://jsfiddle.net/cfarmerga/cp323djx/1/

在此处输入图片说明

Modifying your dofollowup to return the deferred seems to fix this.

var dofollowup = function (value) {

  log("Doing follow-up work for " + value);

  var to_do = Q();
  for (var i=0; i<5; i++) {
    to_do = to_do.then(function () {
      var deferred = Q.defer();
      setTimeout(function () {
        log("Doing delayed work for " + value);
        deferred.resolve();
      }, 100);
      return deferred.promise; //you forgot this..
    });
  }
  return to_do;

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM