While I am quite familiar with coding in JavaScript, the benefits of promises in the JS world still seem somewhat unclear to me. Below is an example of asynchronous calls using callbacks nested within each other.
(function doWorkOldSchool() {
setTimeout(function() {
// When the work is done, resolve the promise
console.log("work done");
setTimeout(function goHome() {
// Once home, resolve the 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 asleep, resolve the promise
console.log("go to sleep");
}, 2000);
}, 2000);
} catch (ex) {
console.log(ex);
}
}, 2000);
}, 2000);
}());
Two main issues arise with this code:
Exceptions thrown inside callbacks are difficult to handle. The exceptions are out of scope and cannot be properly dealt with as they propagate upwards. How can such exceptions be managed?
The nesting structure could lead to deeply nested code that might become unmanageable even if the callback functions are kept separate from the setTimeout code.
Can someone clarify if there are any other significant problems or advantages to this type of coding?
Now, I have restructured the program to accomplish the same tasks using promises:
function doWork() {
return new Promise(function(res, rej) {
// perform asynchronous tasks
setTimeout(function() {
// When the task is complete, resolve the promise
res("work done");
}, 2000);
});
}
function goHome(succ) {
console.log(succ);
return new Promise(function(res, rej) {
// perform asynchronous tasks
setTimeout(function() {
// Once done, resolve the promise
res("got home");
}, 2000);
});
}
// Other functions like cookDinner and goToSleep follow a similar pattern...
doWork()
.then(goHome)
.then(cookDinner)
.then(goToSleep)
.then(function(succ) {
console.log(succ);
}, function(err) {
console.log(err);
});
Compared to the previous solution, this approach seems to eliminate certain drawbacks:
Exceptions thrown inside handlers can now be caught by the error handler further down the chain.
Rejected promises can also be handled by the chained error handler.
The code appears much cleaner and more organized.
Does my understanding align with these advantages, or are there other pros and cons to consider between these two approaches?