JavaScript asynchronous solution Promise full parsing
What is a Promise?
Promise is a JS asynchronous programming solution that solves the problem of traditional asynchronous programming callback hell. Semantically: A Promise is an object that communicates asynchronous programming operation messages to the outside world.
Three states of Promise
A Promise object represents an asynchronous operation with three states:
pending
(In progress)fulfilled
(Completed)rejected
(Failed)
Only the result of an asynchronous operation can determine the current state, and no other operation can change it. Pending is the initial state, and there are only two kinds of state changes:
pending
->fulfilled
(Asynchronous task completed)pending
->rejected
(Asynchronous task failed)
And once the state changes, the state freezes, and it doesn’t change anymore. This results in a Promise being executed as soon as it is created and cannot be cancelled.
Basic use of Promise
ES6 specifies that a Promise is a constructor that generates an instance of a Promise object.
const promise = new Promise(function(resolve,reject){
// Asynchronous operation
if(success){ // The asynchronous operation succeeded
resolve(value);
} else{ // The asynchronous operation failedreject(err); }})Copy the code
The parameter accepted by the Promise constructor is a function that has two arguments specified by the JS engine: the resolve and reject functions
resolve
The function does two things:- Change the Promise state from
pending
->fulfilled
(Wait -> Succeed) - Pass value, the result of the successful asynchronous operation, as a parameter. (Received by the then method)
- Change the Promise state from
reject
The function also has two functions:- Change the Promise state from
pending
->rejected
(Wait -> Fail) - Error message that the asynchronous operation will fail
err
Pass it as an argument. (From the followingthen
/catch
Method receive)
- Change the Promise state from
Promise’s three instance methods then catch finally
1. Promise.prototype.then()
A Promise instance has a THEN method, which is defined on the prototype object. After a Promise instance is generated, you can use the THEN method to specify a callback function in the resolve and Rejected states respectively: get the state of the asynchronous operation inside the Promise.
promise.then(
function (value) {
console.log(value); This is fulfilled when the asynchronous operation is successful
},
function (err) {
console.log(err); // Call when the asynchronous operation fails (rejected state)});Copy the code
The then method can take two callback functions as arguments:
The first callback is called when the Promise instance becomes fulfilled and takes the value passed by the resolve function. The second callback is called when the Promise instance becomes Rejected and takes the err parameter passed by the Reject function. The return value of the then method is a new Promise object, so.THEN can be chained.
2. Promise.prototype.catch()
The catch method of a Promise instance, which specifies the callback function when an error occurs, is the syntactic sugar of.then(null, rejection).
promise
.then(function (val) {
console.log(val); This is fulfilled when the asynchronous operation is successful
})
.catch(function (err) {
console.log(err); // Call when the asynchronous operation fails (rejected state)
});
Copy the code
In the above code, if the promise object state becomes fulfilled, the callback function specified by the THEN method is called. If the asynchronous operation throws an error, the state will be rejected and the callback function specified by the catch method will be called. In addition, the callback function specified by the THEN method is also caught by the catch method if an error is thrown.
promise
.then((val) = > console.log("fulfilled:", val))
.catch((err) = > console.log("rejected:", err));
/ / equivalent to the
promise
.then((val) = > console.log("fulfilled:", val))
.then(null.(err) = > console.log("rejected:", err));
Copy the code
If the Promise state has changed to Resolved, throwing an error is invalid. Once a Promise’s state changes, it stays in that state forever and never changes again. The error of a Promise object bubbles and is passed back until it is caught, meaning that the error is always caught by the next catch statement.
3. Promise.prototype.finally()
The finally method of a Promise instance is used to specify a function that will execute regardless of the final state. Is the syntax sugar for.then(function,function) (same as function).
promise.finally((message) = > console.log(The state has changed., message));
/ / equivalent to the
promise.then(
(message) = > console.log(The state has changed., message),
(message) = > console.log(The state has changed., message)
);
// Execute on success or failure
Copy the code
Promise’s two static methods, all and Race
1. Promise.all()
The promise. all(arr) method is a static method mounted on the Promise constructor. It takes an array of Promise objects, arr, and returns a Promise instance:
This instance will call the internal resolve function when the state of all the objects in the Promise array becomes fulfilled. This instance calls the Reject function when the state of any object in the Promise array becomes Rejected (reject takes the err of the first promiser). This is similar to the and operation (&&) in JS: return true if all expressions are true, and false if any expressions are false.
let p1 = new Promise((resolve,reject) = >{
resolve('p1-success'})),let p2 = new Promise((resolve,reject) = >{
resolve('p2-success'})),let p3 = new Promise((resolve,reject) = >{
reject('p1-error'})),Promise.all([p1,p2,p3]).then(val= >{
console.log(val)
}).catch(err= >{
console.log(err)
})
/ / output p1 - error
Copy the code
It is important to note that the array of successful results obtained by promise.all () is in the same order as the array received by promise.all (), that is, p1 comes first, even though P1 is obtained later than P2. This brings a huge benefit: while developing request data on the front end, promise.all () can certainly solve the problem of occasionally sending multiple requests and getting and using the data in the order of the requests.
2. Promise.race()
The promise.race (arR) method returns a Promise instance that will be resolved or rejected once one of the Promise objects in the ARR is resolved or rejected. A promise.race ([p1, P2, p3]) returns a result that is faster, regardless of whether the result itself is a success or a failure.
let p1 = new Promise((resolve, reject) = > {
setTimeout(() = > {
resolve("p1-success");
}, 1000);
});
let p2 = new Promise((resolve, reject) = > {
setTimeout(() = > {
resolve("p2-success");
}, 500);
});
let p3 = new Promise((resolve, reject) = > {
setTimeout(() = > {
reject("p3-error");
}, 1000);
});
Promise.race([p1, p2, p3])
.then((val) = > {
console.log(val);
})
.catch((err) = > {
console.log(err);
});
/ / output p2 - success
Copy the code