- Making a network call, then taking some action when it is completed.
- Waiting for the user to interact with some input control.
- Wrapping one or more callbacks for improved code readability.
- Waiting for some predetermined period of time before proceeding.
- Loading external resources.
Creating a Promise
- resolve: when the action taken in the function is completed, call resolve and pass in the value to be returned.
- reject: if we need to throw an error, we can pass the error into this function to indicate that an error has occurred.
In the code example below, we create a promise which resolves after a few seconds:
- A new Promise is created with a function passed into its first parameter, which we will call the "constructor function".
- The constructor function is invoked with two arguments: resolve and reject. Both of those arguments are themselves functions.
- The constructor function does what it needs to do, then will either end in a happy state or error state.
- If it ends in a "happy" state, it will call resolve and pass in the return value as an argument.
- If it ends in an error state, it will call reject and pass in the error value as an argument.
- If it does not call resolve or reject, the Promise will never resolve.
Reacting to a Promise
- then: a method which will invoke a callback if the Promise resolves in a non-error state. The Promise's return value is passed into the callback as an argument.
- catch: a method which will invoke a callback if the Promise rejects. The error thrown is passed into the callback as an argument.
- finally: a method which will invoke a callback regardless of the Promise's state. This can be useful for de-allocating resources, logging, or any other action which needs to happen regardless if the promise succeeds or fails.
The code example below uses all three methods described above. Notice that we are chaining the calls. When we call then, catch, or finally, the method itself returns a new Promise which we can then add another then, catch, or finally. The value returned from the callback method will be the value which the new Promise object resolves to, or rejects to if an error is thrown.
A powerful feature of .catch: the callback can return a different value and the resulting promise will resolve to that other value. This allows us to gracefully handle errors. The code below catches a bad network call and returns an object of the same type the system expects.
It is also worth noting that callbacks can themselves return promises. If they do, the resulting Promise will resolve or reject when the Promise returned in the callback resolves or rejects, as demonstrated in the example below:
Async and Await
- Mark a function as asynchronous: put the "async" keyword infront of the function declaration.
- Await a Promise: put the "await" keyword in front of a Promise to indicate that we will await its completion.
The code box below shows a function with async/await, then a similar piece of code without it. Note that we can use try/catch blocks with the await syntax.