I promise, you will understand Promise after reading this (Part I)
03 Aug 2019
Reading time ~3 minutes
What is Promise?
Promise was introduced in ES6 to help manage async operations in a clearer manner.
Want me to elaborate on “in a clearer manner”? Let’s find out how Promise made things easier when dealing with async operations in JavaScript.
Prior to the introduction of Promise
, a popular pattern when dealing with async operations was to chain async functions with callbacks. See TIL callback for what I mean by this. This traditional pattern had a few problems associated with it:
(1) callback hell
- the code is hard to follow as the size of callback hell increases
- indentation depth increases due to nesting of the callback functions
(2) dealing with errors
- the traditional callback pattern makes it difficult to deal with errors in async operations
Take a look at below example:
try {
setTimeout(() => { throw new Error('Error!'); }, 1000);
} catch (e) {
console.log(e);
}
reference: poiemaweb]
The
try
statement lets you test a block of code for errors.The
catch
statement lets you handle the error.The
throw
statement lets you create custom errors.reference: w3schools
At first glance, it looks like an error will be thrown 1 second after execution in the try
block. Then the catch
block will handle the error thrown from the try
block by logging the error in console.
However, the catch
block will not catch any error.
Hmm. Let’s examine the code in close detail to figure out why.
Function setTimeout
takes in a callback function, which throws an error, as its first argument. The callback function is executed after approximately 1000 milliseconds.
For those who are not familiar with event loop, here are the steps on how the callback function in setTimeout
is eventually called:
-
function
setTimeout
is added to the call stack and is immediately called. -
function
setTimeout
completes execution, and is removed from the call stack. -
On its execution, it’s callback function remains outside of call stack, and the callback function will listen for a specific event and will be added it to callback queue until the event occurs. In this case, when
timer
function’stick
event marks 1000 milliseconds, the callback function is added to the callback queue. -
The event loop will only add functions to call stack from callback queue when the call stack is empty. So, the callback function will be added to the call stack when it is empty.
-
Callback function is added to the stack, throws an error, and leaves the stack on its completion.
Execeptions propagate to the caller: errors thrown by callees will be propagated up to the caller. In above example, the error is thrown by the callback function. It may intuitively appear that the setTimeout
function is the caller of the callback function, but setTimeout
leaves the call stack after its execution. This means that the caller of the callback function is not setTimeout
.
So the error is thrown into some void in computer world and it can never be caught with catch
in this manner.
Promise
supplements callback hell and error handling in traditional async pattern. And for these reasons, Promise
is one of the features introduced in ES6 and is compatiable with most browsers except for IE.
Up next is how to use Promise
.
…to be continued in What is Promise? Part II