new Promise(function(resolve, reject){
setTimeout(function(){ reject('an error happened!'); }, 1500);
}).catch(function(error){
console.log(`error: ${error}`);
}).then(function(result){
console.log("all done!");
});
"all done" will fire every time even if the promise is rejected.
new Promise(function(resolve, reject){
setTimeout(function(){ reject('an error happened!'); }, 1500);
}).then(function(result){
console.log("all done!");
}).catch(function(error){
console.log(`error: ${error}`);
});
now "all done" only fires if catch() doesn't. makes no sense, and having the catch immediately adjascent to the code you tried to execute is hella more readable to me, but there you have it.
If, like me, you're hellbent on having your catches up front you can catch it with a variable external to the catch/then scope but it's still kinda nasty:
let abort = false;
new Promise(function(resolve, reject){
setTimeout(function(){ reject('an error happened!'); }, 1500);
}).catch(function(error){
abort = true;
console.log(`error: ${error}`);
}).then(function(result){
if (! abort){ console.log("all done!"); }
});
if you wanna do the catch first with a Promise.all()
you need to be aware that the .catch()
function will fire immediately
on the first rejected promise in the array, regardless of the resolution status of the remaining promises in the array
let blah = [];
blah.push(new Promise(function(t,b){ setTimeout(function(){
console.log('resolve 1500');
t(true);
}, 1500); }));
blah.push(new Promise(function(t,b){ setTimeout(function(){
console.log('resolve 2500');
t(true);
}, 2500); }));
blah.push(new Promise(function(t,b){ setTimeout(function(){
console.log('reject 150');
b('wtf');
}, 150); }));
let abrt = false;
Promise.all(blah).catch(function(error){
console.log(`error: ${error}`);
abrt = true;
}).then(function(){
if (! abrt){ console.log("all done"); }
});
the above will fail to fire the "all done", true enough, but it fires the "error: " console.log call before the other promises in the array resolve.
Your catch()
block will fire before all promises in the Promise.all()
resolve.
putting the catch()
block last does not change the behavior beyond no longer needing the abort flag to prevent the
then()
block running:
let blah = [];
blah.push(new Promise(function(t,b){ setTimeout(function(){
console.log('resolve 1500');
t(true);
}, 1500); }));
blah.push(new Promise(function(t,b){ setTimeout(function(){
console.log('resolve 2500');
t(true);
}, 2500); }));
blah.push(new Promise(function(t,b){ setTimeout(function(){
console.log('reject 150');
b('wtf');
}, 150); }));
Promise.all(blah).then(function(){
console.log("all done");
}).catch(function(error){
console.log(`error: ${error}`);
});
Which I suppose makes sense as Promise.all()
itself returns a promise that behaves like every other
promise. That being the case, I don't see this behavior called out in either the WC3 spec nor the
vernerable MDN docs. Seemed worth mentioning somewhere on the internet