A brief explainer (for future-me and anyone else it helps) on what promises are and how to use them. Note: this is not an official definition, but rather one that works for me.
A Promise is an object we use for asynchronous operations. It’s a proxy for the success value or failure reason of the asynchronous operation, which at the time the promise is created is not necessarily yet known.
A promise is in one of three states:
- fulfilled (the operation completed successfully)
- rejected (the operation failed)
We say a pending promise can go on to be either fulfilled with a value, or rejected with a reason (error).
We also talk about a promise being settled when it is no longer pending.
One memorable analogy was provided in Mariko Kosaka’s The Promise of a Burger Party. In it she describes the scenario of ordering a burger from, say, Burger King. It goes something like this:
- you place your order for a Whopper;
- they give you a tray with a buzzer. The tray is a promise that they will provide your burger as soon as it has been cooked, and the buzzer is the promise‘s state;
- the buzzer is not buzzing to start with: it’s in the pending state;
- the buzzer buzzes: the promise is now settled;
- they might inform you that their flame-grill broke down half-way through. The cooking operation failed, and the promise of a burger has been rejected with that reason. You’ll likely want to act on that (by getting a refund);
- alternatively all goes to plan, you go the counter and they fulfil their promise of a tasty burger placed onto your tray.
- you decide you want to act on the success of getting your tasty burger by doing another thing, namely buying a coke. In code you’ll be within the
.then()method which is the success handler for your promise and in there you can just call
buyCoke(). (Note: the
buyCoke()operation might be synchronous; the real life analogy being that it’s so quick to pour a coke that the assistant does it and serves it on a tray immediately rather than giving you a tray as a promise for it.) At the end of your
then()you might choose to return a
mealobject which combines your burger and coke.
- You could then chain a further
.then()to the original
.then()to work with your snowballing data value. This is because
then()methods always return a promise (even if the operation within was not asynchronous), and we already know that promises are thenable (i.e. have a
then()method) hence our ability to keep chaining.
There are two things we need to be able to do with promises:
- create and return them;
- work with a returned promise.
Create and return a promise
When you create a promise you pass a function known as the executor to it, which runs instantly. Its arguments