You already know that using the async callback model easily leads to a callback hell situation. Therefore, a new model called promises was introduced in JavaScript. Let's examine this model.
A promise is an object to which a function is passed as a parameter, inside which we need to place our asynchronous code:
let promise = new Promise(function() {
// an async code
});
As you can see, I've stored the promise
object in the promise
variable.
Somewhere else in the code, I can apply
the then
method to this variable,
passing a function to it with a code
that should be executed when the async
code written when this promise was
created completes:
promise.then(function() {
// it will be executed when the async code completes
});
It sounds confusing, so let's look at an example. Let me have this async code:
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
Suppose I want to solve our main asynchrony
issue for it: execute some code after the
timer fires. At the same time, I don't want
to place this code in the timer itself and
I want the result written by me in the
result
variable to somehow get
into this code. In general, we solved
this issue in previous lessons via
callbacks and subscriptions. Let's now
see how to do this via promises.
First we need to wrap our async code in a promise:
let promise = new Promise(function() {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
This, however, is not enough. We must explicitly indicate that our async code has completed. A special completion function will help us with it, automatically falling into the first function parameter, if it is specified:
let promise = new Promise(function(resolve) { // we specify a parameter
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
With the completion function, we can explicitly tell the promise that the async code has completed. To do this, we must invoke this function in the place we need:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(); // we complete the promise
}, 3000);
});
At the same time, if we want to pass some result of async code outside, we can pass it as a parameter to our completion function:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(result); // we pass the result
}, 3000);
});
You can, of course, get rid of the intermediate variable:
let promise = new Promise(function(resolve) {
setTimeout(function() {
resolve([1, 2, 3, 4, 5]);
}, 3000);
});
Now in any other place we can
call the then
method of
our promise:
promise.then(function() {
// will be triggered when the promise is completed
});
The result of the promise will fall into the first parameter of the function, if we wish to specify it:
promise.then(function(result) {
console.log(result); // will output an array with the result
});
Make a promise, inside which there
will be a delay of 5
seconds,
after which the promise should be
fulfilled, returning some text as
its result. Display this text on
the screen.