1. Promise
Promise is a solution to asynchronous programming that is more reasonable and powerful than the traditional solution of callback functions and events.
1.1 What is Promise
Simply put, it is a container that holds the result of some event that will end in the future (that is, an asynchronous operation). Syntactically, a Promise is an object from which you can retrieve messages for asynchronous operations, and it provides a unified API from which all asynchronous operations can be handled in the same way.
Promise has two features:
1.1.1 The status of the object is not affected by the outside world. The Promise object represents an asynchronous operation with three states: Pending, fulfilled and Rejected. Only the result of an asynchronous operation can determine which state is currently in, and no other operation can modify that state.
1.1.2 Once the status is changed, it will not change again, and this result can be obtained at any time. There are only two possibilities for the state of a Promise object to change: from Pending to pity or from pending to rejeced. As soon as those two things happen, the state stops, it doesn’t change anymore and it stays that way. This is called resolved. If the change has already occurred, even if you add a callback to the Promise object, you will get this result immediately. If you try to listen in after you’ve missed it, it won’t work.
1.1.3 With the Promise object, asynchronous operations can be displayed as a flow of synchronous operations, eliminating the need for nested layers of callback functions. Promise objects provide a unified interface that makes it easier to control asynchronous operations.
1.1.4 Promises also have some disadvantages, that is, they cannot be cancelled. Once a Promise is established, it will be executed immediately and cannot be cancelled midway. If the callback function is not set, errors thrown inside a Promise will not be reflected externally. In addition, if the state is pending, there is no way to know which stage it is in.
2. Basic usage
The Promise object is a constructor that generates a Promise instance
const promise = new Promise((reolve, reject) => {
ifResolve (val)}else{
reject(val)
}
})
Copy the code
The Promise constructor takes a function as an argument, resolve and reject.
Resolve:, changes the state of the Promise object from ‘unfinished’ to ‘successful’ (pending => Resolved), which is called when the asynchronous operation succeeds and passes the result of the asynchronous operation as a parameter.
Reject: Changes the state of the Promise object from “unfinished” to “failed” (pending => Rejected), which is called when the asynchronous operation fails and passes the result of the asynchronous operation as a parameter.
After the Promise instance is generated, you can use the THEN method to specify the resolved and Rejected state callback functions, respectively.
promise.then((val) => {
// success
},(err) => {
// failure
})
Copy the code
The then method can take two callback functions as arguments. (The second function is optional, and both functions accept the value passed from the Promise object as an argument.)
1. The first callback is called when the State of the Promise object changes to “Resolved.”
The second callback is called when the state of the Promise object changes to “Rejected”.
Example:function timeout(ms) {
retrun new Promise((resolve, reject) => {
setTimeout(resolve, ms, 'done')
})
}
timeout(100)
.then((v) => {
console.log(v)
})
Copy the code
In the code above, the timeout method returns an instance of a Promise that will occur some time later. After ms time, the Promise state changes to “resolved” and the callback bound to the then method is triggered.
Promises are implemented immediately after they are made
let promise = new Promise((resolve, reject) => {
console.log('Promise')
resolve()
})
promise
.then(() => {
console.log('resolved')
})
console.log('hh')
// Promise
// hh
// resolved
Copy the code
When a Promise is established, execute as soon as possible, first printing “Promise” and then executing the Promise’s then function. Then execute the synchronization task first and output HH. Then execute the then callback and output Resolved
If resolve and reject are called with arguments, their arguments are passed to the callback function. The argument to the Reject function is usually an instance of the Error object, representing the Error thrown. The argument to the resolve function may be an instance of a Promise in addition to the normal value. Resolve is called when complete success occurs, reject is called when failure occurs.
const p1 = new Promise(function (resolve, reject) {
// ...
});
const p2 = new Promise(function (resolve, reject) {
// ...
resolve(p1);
})
Copy the code
In the code above: P1 and p2 are both instances of Promise, but P2’s resolve method takes P1 as an argument, meaning that the result of an asynchronous operation is returned by another asynchronous operation.
Note: the state of P1 is passed to P2, and the state of P1 determines the state of P2. If P1’s state is pending, p2’s callback waits for p1’s state to change. If P1 is in resolved or Rejected, the P2 callback will be executed immediately.
In general, a call to resolve or Reject ends the Promise process, and subsequent actions should be placed in the then method rather than directly after resolve or Reject. And finally, add a return statement before them.
3. Promise.prototype.then()
Promise instances have then methods defined on the prototype object Promise.Prototype. It adds a callback function to the Promise instance when the state changes. The first argument to then is the resolved state callback and the second argument is the Rejected state callback.
The then method returns a new Promise instance, not the original one, so you can use the chain notation. .then().then()
a().then((j) => {
retrun j
}).then((i) => {
console.log(i)
},(err)=>{
console.log(err)
})
Copy the code
The callback specified by the first THEN method above returns another Promise object. The callback specified by the second then method waits for the new Promise object state to change and calls the first callback if it changes to Resolved, and the second callback if it changes to Rejected.
4. Promise.prototype.catch()
The promise.prototype. catch method is an alias for.then(null, rejecton) or.then(undefined, Rejection) to specify the callback when an error occurs.
a().then((p) => {
// success
}).catch((err) => {
console.log('err')})Copy the code
If the object’s state changes to Resolved, the success callback specified by the then method is called. If the asynchronous operation throws an error, the status changes to Rejected and the callback specified by the catch method is called to handle the error. If a callback specified by the then method throws an error at run time, it will also be caught by the catch method.
The reject method also does the same thing as throwing an error
If the Promise state has changed to Resolved, throwing an error is invalid. Because once the state changes, it stays there forever. It never changes. Moreover, Promise errors have a “bubbling” nature, passing them backwards until they are caught, and their errors are always caught by the next catch statement.
Suggestion: Follow a catch method after a Promise object to handle errors within a Promise. The catch method still returns a Promise object, so you can call the then method later.
If there is no catch following it, the error will not be caught. If there is a catch following it, the second catch will catch the error thrown by the previous catch.
5. Promise.prototype.finally()
The finally method is used to specify actions that will be performed regardless of the final state of the Promise object.
Promise. Then (result = > {...}). The catch (error = > {...}), finally (() = > {...});Copy the code
Above, regardless of the final state of the promise, the function specified by the finally method is executed.
The callback function of the finally method does not accept any parameters, so there is no way to know whether the Promise state is fulfilled or rejected. So the actions in the finally method are independent of the previous state and do not depend on the result of the Promise’s execution.
6. Promise.all()
The promise.all method is used to wrap multiple Promise instances into a new Promise instance.
const p = Promise.all([p1, p2, p3])
Copy the code
The promise. all method takes an array as an argument. P1, P2, and p3 are all Promise instances. (The promise. all method can take arguments that are not arrays, but must have an Iterator interface and return each member as a Promise instance.)
Promise.all has two states:
1. If the states of P1, P2, p3 are all fulfilled, the state of P is fulfilled. At this time, an array of return values of P1, P2, p3 will be returned and passed to the callback function of P.
P = rejected (p1, P2, p3); p = rejected (p1, P2, p3); p = rejected (p1, P2, p3);
Note that if a Promise instance that is a parameter defines its own catch method, it does not fire the promise.all () catch method once it is rejected. Instead, you trigger your own catch method.
7. Promise.race()
The promise.race method also wraps multiple Promise instances into a new Promise instance.
const p = Promise.race([p1, p2, p3]);
Copy the code
The difference with promise. all is that when an instance of p1, P2, p3 changes state, p changes state, and the return value is the first return value of the Promise instance.
8. Promise.resolve()
Turn an existing object into a Promise object.
1. If the argument is an instance of Promise
Then no changes will be made.Copy the code
2. The argument is a Thenable object.
Turn this object into a Promise object, and immediately execute the then method of the Thenable objectCopy the code
3. Parameters are not objects with then methods, or not objects at all
Return a new Promise object with the status ResolvedCopy the code
4. No parameters
Return an Resolved Promise object directlyCopy the code
9. Promise.reject()
The promise.Reject (Reason) method also returns a new Promise instance with a state of Rejected. The callback function executes immediately.