- Provide simple examples which you can run in your browser’s console
- Demonstrate the flow of promise execution
Before we jump into the examples, let’s quickly review the basics of promises.
3 states of a promise
A Promise will always be in one of three states:
- pending: This is the initial state when it is just created.
- fulfilled: This indicates that the operation that the promised wrapped completed successfully
- rejected: This indicates that the operation that the promise wrapped had failed
If a promise is resolved/fulfilled the success callback will be called and if it’s rejected, the failure callback will be called. If you are curious about how callbacks work read this article.
Now let’s understand what happens when promises get resolved or rejected.
We will simulate a resolved promise using the
Promise.reject() method. It can be replace with asynchronous operation.
If the promise has already been fulfilled or rejected when a corresponding handler is attached, the handler will be called, so there is no race condition between an asynchronous operation completing and its handlers being attached.
As the Promise.prototype.then() and Promise.prototype.catch() methods return promises, they can be chained—an operation called composition.
Promise.resolve() with return statements.
Promise.resolve() returns Promise object that is resolved with the given value. Promise.reject() returns a Promise object that is rejected with the given reason.
That was pretty straightforward. But promises also support chaining. You can pass a value to the next function in the promise chain using return statements. This is probably how you will find yourself using promises a lot in your own projects.
Things become a little more interesting when you return promises from within promises.
In the above case, the inner promise of the first then block must get resolved before the success handler of the last then block can execute.
Repeat the similar exercise for
Promise.reject() callback flows. I would encourage you to try the exercise with
Promise.reject() on your own and observe the behavior and come back to this article to compare your exercise.
When a promise is rejected and there is no error handler, none of the consecutive success handlers in the chain are invoked until a failure handler is encountered.
Here’s another example where you just have a catch function at the end of the chain. This behaves very similar to a finally clause.
Once a promise failure is handled, subsequence items in the chain can proceed as normal. For example
In the examples above, you’ve seen that when you return something from within a then block, the next success handler receives that value. There is only one special case under which this fact does not hold true, and that is when the argument to then is null. In such cases, the first then block in the promise chain that has a function as a handler receives the value.
Normally, this is what happens
But when you interleave then’s with null callbacks, the behaviour changes slightly