In testing I\'ve found that JavaScript Promises are always asynchronous regardless of whether or not they contain any asynchronous functions in their chain.
Your code is fine is you want your promises to run independently and let them execute in their own way, no matter each one complete first. As soon as your code is async, you cannot predict which one will be completed first (due to the async nature of the event loop
).
However if you want to catch all your promises after they all completed, you should use Promise.all
(which is the equivalent of $.when
is jQuery).
See:
The callback passed to a Promise constructor is always called synchronously, but the callbacks passed into then
are always called asynchronously (you could use setTimeout
with a delay of 0
in a userland implementation to achieve that).
Simplifying your example (and giving the anonymous function's names so I can refer to them) to:
Promise.resolve().then(function callbackA () {
console.log("finish run 1");
}).then(function callbackB () {
console.log("surprisingly this happens after run 2 finishes");
});
Promise.resolve().then(function callbackC () {
console.log("finish run 2");
})
Still gives the output in the same order:
finish run 1
finish run 2
surprisingly this happens after run 2 finishes
Events happen in this order:
The easiest way I can think of to work around your problem is to use a library that has an Promise.prototype.isFulfilled function you can use to decide whether to call your second callback synchronously or not. For example:
var Promise = require( 'bluebird' );
Promise.prototype._SEPH_syncThen = function ( callback ) {
return (
this.isPending()
? this.then( callback )
: Promise.resolve( callback( this.value() ) )
);
}
Promise.resolve()._SEPH_syncThen(function callbackA () {
console.log("finish run 1");
})._SEPH_syncThen(function callbackB () {
console.log("surprisingly this happens after run 2 finishes");
});
Promise.resolve()._SEPH_syncThen(function callbackC () {
console.log("finish run 2");
})
This outputs:
finish run 1
surprisingly this happens after run 2 finishes
finish run 2