I code JavaScript quite a bit and although I think I do understand workings of promises I'm not sure if I fully understand advantages that promises bring to JS world. Consider code below, simply asynchronous calls with callbacks containing furhter calls and so on.
(function doWorkOldSchool() {
setTimeout(function() {
// once done resolve promise
console.log("work done");
setTimeout(function goHome() {
// once done resolve promise
console.log("got home");
try {
setTimeout(function cookDinner() {
// this exception will not be caught
throw "No ingredients for dinner!";
console.log("dinner cooked");
setTimeout(function goToSleep() {
// once done resolve promise
console.log("go to sleep");
}, 2000);
}, 2000);
} catch (ex) {
console.log(ex);
}
}, 2000);
}, 2000);
}());
One problem I see with this:
Exceptions thrown inside of callbacks are useless. Is it correct to say that as throw calls happen these throw calls are out of scope hence the exception cannot be called and bubbles all the way to the top? How this sort of exception can be dealt with?
Second problem I see that this nesting business might get really deep and even though you can keep callback functions code outside of the setTimeout code, it might become a mess.
So first could someone please clarify if there is anything else that is obvious problem or advantage of this sort of coding?
Now, below I prepared program that does the same thing really, but this time using promises:
function doWork() {
return new Promise(function(res, rej) {
// do your asynchronous stuff
setTimeout(function() {
// once done resolve promise
res("work done");
}, 2000);
});
}
function goHome(succ) {
console.log(succ);
return new Promise(function(res, rej) {
// do your asynchronous stuff
setTimeout(function() {
// once done resolve promise
res("got home");
}, 2000);
});
}
function cookDinner(succ) {
console.log(succ);
//if exception thrown here it will be caught by chained err handler
throw "No ingredients for dinner Exception!";
return new Promise(function(res, rej) {
// do your asynchronous stuff
setTimeout(function() {
// something went wrong so instead of using throw we reject the promise
rej("No ingredients for dinner!");
// once done resolve promise
}, 2000);
});
}
function goToSleep(succ) {
console.log(succ);
return new Promise(function(res, rej) {
// do your asynchronous stuff
setTimeout(function() {
// once done resolve promise
res("zzz... zz..");
}, 2000);
});
}
doWork()
.then(goHome)
.then(cookDinner)
.then(goToSleep)
.then(function(succ) {
console.log(succ);
}, function(err) {
console.log(err);
});
Comparing to previous solution I see no obvious problems with this approach, apart from you obviously must have understanding of promises to code/maintain this thing. Advantages would be however:
the exception thrown INSIDE OF handlers will be caught in err handler that is chained somewhere further.
the rejected Promises will be caught by chained err handler
the code is much cleaner
Now, is my understanding correct or are there any other advantages/disadvantages of each approach?