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?
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.