Promises are a solution to asynchronous programming: syntactically, promises are an object from which to retrieve messages for asynchronous operations. Promise has three states: pending, fulfiled, and Rejected. Once the state has changed, it will never change. Once a Promise instance is created, it executes immediately.

Promises are used to solve problems:

  • Callback hell, code is difficult to maintain, often the output of the first function is the input of the second function

  • Promises can support multiple concurrent requests, retrieving data from concurrent requests

  • Promises solve the problem of asynchrony, not asynchrony per se

Es6 promise

Promise is a constructor with familiar methods all, Reject, and resolve on its own, and equally familiar methods like THEN and catch on its prototype.

Let’s have a new one

Let p = new Promise((resolve, reject) => {// do something asynchronous setTimeout(() => {console.log(' done '); Resolve (' I am success!! '); }, 2000); });Copy the code

The Promise constructor takes one argument: the function, and this function takes two arguments:

  • Resolve: Callback function after asynchronous operation is successfully executed

  • Reject: Callback function when an asynchronous operation fails

Then chain operation usage

Therefore, on the surface, Promise can only simplify the writing method of layer upon layer callback. In essence, the essence of Promise is “state”, which can be invoked in time by maintaining state and transferring state. It is much simpler and more flexible than passing callback function. So the correct scenario for using promises looks like this:

p.then((data) => {
    console.log(data);
})
.then((data) => {
    console.log(data);
})
.then((data) => {
    console.log(data);
});
Copy the code

Reject:

Set the state of the Promise to Rejected so that we can capture it in THEN and perform the “failed” callback. Look at the code below.

Let p = new Promise((resolve, reject) => {var num = math.ceil (math.random ()*10); If (num<=5){resolve(num); } else{reject(' numbers are too large '); }}, 2000); }); p.then((data) => { console.log('resolved',data); },(err) => { console.log('rejected',err); });Copy the code

Two arguments are passed in then, and the THEN method can accept two arguments, the first corresponding to the resolve callback and the second to the reject callback. So we were able to get the data separately from them. Run this code many times and you will get one of two random results:

or

The use of the catch

We know that a Promise object has a catch method as well as a then method, so what does that do? This, like the second argument to THEN, specifies the reject callback. Here’s how it works:

p.then((data) => {
    console.log('resolved',data);
}).catch((err) => {
    console.log('rejected',err);
});
Copy the code

The effect is the same as in the second argument to then. However, it also serves another purpose: if an exception is thrown when the resolve callback (the first argument to then above) is executed, it does not trap the JS, but instead goes into the catch method. Take a look at the following code:

p.then((data) => { console.log('resolved',data); console.log(somedata); // SomeData undefined}). Catch ((err) => {console.log('rejected',err); });Copy the code

In the resolve callback, we console.log(somedata); The variable someData is undefined. If we don’t use the Promise, the code will run here and we’ll just get an error on the console and stop running. But here, you get something like this:

That is, it is inside the catch method and passes the cause of the error to the reason argument. Even if the code has an error, it will not report an error, which has the same functionality as our try/catch statement

The callback is performed based on the slower-running all. All takes an array of arguments, and the values in it eventually return a Promise object

Promise’s All method provides the ability to execute asynchronous operations in parallel and not execute callbacks until all asynchronous operations have been executed. Look at the following example:

let Promise1 = new Promise(function(resolve, reject){}) let Promise2 = new Promise(function(resolve, reject){}) let Promise3 = new Promise(function(resolve, reject){}) let p = Promise.all([Promise1, Promise2, (funciton(){function(){function(){function(){function(){function(){function(){function(){function(){Copy the code

With ALL, you can perform multiple asynchronous operations in parallel and process all the returned data in a single callback. Isn’t that cool? There is a scene is very suitable for this, some game materials more applications, when opening the web page, pre-load the need to use a variety of resources such as pictures, Flash and various static files. After everything is loaded, we’ll initialize the page.

The callback is based on the fastest runner

For example, we can use race to set a timeout for an asynchronous request and perform the corresponding operation after the timeout, as follows:

Function requestImg(){var p = new Promise((resolve, reject) => {var img = new Image(); img.onload = function(){ resolve(img); } img. SRC = 'image path '; }); return p; Var p = new Promise((resolve, reject) => {setTimeout(() => {reject(' reject ')); }, 5000); }); return p; } Promise.race([requestImg(), timeout()]).then((data) =>{ console.log(data); }).catch((err) => { console.log(err); });Copy the code

The requestImg function asynchronously requests an image, and I wrote the address as “path to the image”, so it will definitely fail. The timeout function is an asynchronous operation with a delay of 5 seconds. We put the two functions that return the Promise object into race, and they race. If the image request is successful within 5 seconds, then the normal process is followed. If the image is not returned within 5 seconds, timeout wins and a catch message is displayed indicating that the image request has timed out. The running results are as follows:

Async await and promise

async function async1() { console.log('async1 start'); await async2(); console.log('async1 end'); } // async function async1() {console.log('async1 start'); Promise.resolve(async2()).then(() => { console.log('async1 end'); })}Copy the code