Reputation: 21
I've been playing with Promises and I put together the following code that isn't acting like I'm expecting it to. You can run it in a Fiddle here:
https://fiddle.sencha.com/#view/editor&fiddle/1pmk
function log(txt) {
var lapsed = new Date().getTime() - START;
console.log(lapsed, txt);
}
START = new Date().getTime();
var promise = new Promise(function promiseExecutor(resolve, reject) {
log('in Promise 1 Executor');
setTimeout(function onSetTimeout() {
log('in Promise 1 Timeout');
resolve(123);
}, 500);
});
var promise2 = new Promise(function promise2Executor(resolve, reject) {
log('in Promise 2 Executor');
setTimeout(function onSetTimeout() {
log('in Promise 2 Timeout');
resolve(123);
}, 1000);
});
// sequence
promise
.then(promise2)
.then(function onPromiseDone(p) {
// TODO: why this executes before promise2 resolve?
log('ALL Promise Done! ' + p);
});
If you watch the Console, you'll notice that the "ALL Promise Done" message is fired immediately after the FIRST promise is resolved, and then half a second later the 2nd promise is resolved...
How is it possible that the final then(onPromiseDone) is fired without resolve()?
Now, I understand that the Promise executor function starts running immediately, and this here is not a good example for "sequencing". I am able to achieve the correct behavior by wrapping my promises in "deferred" functions as shown here:
https://fiddle.sencha.com/#view/editor&fiddle/1pml
Still, this doesn't answer my question for the original fiddle, which I'll repeat:
How is it possible that the final then(onPromiseDone) is fired without resolve()?
Thanks!
Upvotes: 0
Views: 4097
Reputation: 7258
.then
receives two arguments: a function that triggers when the Promise successfully resolves and a function that's invoked when the Promise is rejected (can be ommited).
In your example, you're passing a new promisse as an argument.
In order to achieve your goal (chain), I suggest something like that:
var promise = new Promise(function (resolve, reject) {
log('in Promise 1 Executor');
setTimeout(function onSetTimeout() {
log('in Promise 1 Timeout');
resolve(123);
}, 2000);
});
var callback = function(val) {
log('received from the first promisse: ' + val)
return new Promise(function (resolve, reject) {
log('in Promise 2 Executor');
setTimeout(function onSetTimeout() {
log('in Promise 2 Timeout');
resolve(456);
}, 2000);
});
}
// Promise.all([promise, promise2]) // parallelize
// sequence
promise
.then(callback)
.then(function(val) {
log('received from the second promisse: ' + val)
log('ALL Promise Done! ');
}
);
This way, you run your promisse
and set the callback
function as .then
parameter. So, just when the first setTimeout
finishes, it will call resolve
and invoke callback
function, that will create a new Promise and then set the new setTimeout
.
Will output:
0 "in Promise 1 Executor"
2002 "in Promise 1 Timeout"
2002 "received from the first promisse: 123"
2002 "in Promise 2 Executor"
4002 "in Promise 2 Timeout"
4003 "received from the second promisse: 456"
4003 "ALL Promise Done! "
Edited after @Bergi's comment. Thanks.
Upvotes: 1