promise Key points
The ‘Promise’ object represents an asynchronous operation with three states: ‘pending’ (in progress), ‘fulfilled’ (successful), and ‘rejected’ (failed)
A Promise must be in one of the following states:
- pending: An initial state that is neither cashed nor rejected.
- fulfilled: The operation is fulfilled successfully.
- rejected: It indicates that the operation has failed.
When a promise is called, it starts with a processing state ** ‘(pending). This means that the called function continues to execute while the promise remains in processing until it is resolved, providing the calling function with whatever data it requests.
The created promise ends up in the ** resolved state ** ‘(fulfilled)’ or the ** rejected state ** ‘(rejected)’, and the corresponding callback function is called on completion (passed to then and catch).
Features:
1.The initial state of the promise status is pending. Once the promise status is changed, it does not change again.
2.The state of the object is not affected by the outside world. Only the result of asynchronous operations can determine the current state, and any other operations can not change this state
shortcoming:
1.’Promise’ cannot be cancelled, as it will be executed immediately upon creation and cannot be cancelled midway.
If you do not set the callback function, ‘Promise’ internally thrown errors will not be reflected externally.
When in the ‘pending’ state, it is impossible to know which stage of the current progress (just started or about to finish).
1.Define the structure
First define a class:
1 | class myPromise { |
Then, according to the specification promise constructor, we accept a function as an argument, fn. The two arguments of this function are ‘resolve’ and ‘reject’, which is also a function. The ‘resolve’ function is used to change the status of the promise from ‘pending’ to ‘resolved’ and it is called when the asynchronous operation succeeds. The result of the asynchronous operation is passed as a parameter. The ‘reject’ function changes the status of the ‘Promise’ object from ‘pending’ to ‘rejected’ .It is called when the asynchronous operation fails, and passes the error reported by the asynchronous operation as an argument.
1 | // Define the initialization state, the successful value, the failed value, and the array to hold the successful and failed callbacks respectively |
the implement of ‘then’ method
A Promise instance has a ‘then’ method, that is, the ‘then’ method is defined on the prototype object ‘promise.prototype’. Its purpose is to add a callback function to a Promise instance when the state changes. As mentioned earlier, the first argument to the ‘then’ method is the ‘resolved’ status callback function, and the second argument is the ‘rejected’ status callback function, both of which are optional.
The ‘then’ method returns a new ‘Promise’ instance (note, not the original Promise instance). Therefore, it can be written in a chain way, that is, the ‘then’ method is followed by another ‘then’ method.
Because ‘then’ is called after the instance is created, we create another class method
1 | // Define the initialization state, the successful value, the failed value, and the array to hold the successful and failed callbacks respectively |
the implement of ‘resolve’ and ‘reject’ methods
Promise.resolve(value) Converts a given value to a Promise object.
- If the value is a promise, the promise is returned;
- If the value is thenable (that is, with a “then” method), the returned promise will “follow “the thenable object, taking its final state;
- Otherwise, the returned promise will be fulfilled with this value, which is the value at which the ‘resolve()’ method is performed (the status is fulfilled).
Promise.reject()
method returns a ‘Promise’ object with a reason for the rejection
1 | resolve(value) { |
the implement of ‘catch’ method
The ‘catch()’ method returns a ‘Promise’ and handles the rejection case. It behaves the same as calling ‘Promise.prototype.then(undefined, onRejected)’.
In fact, calling ‘obj.catch(onRejected)’ ‘internal calls’ obj.then(undefined, onRejected)’. (This means that we explicitly use ‘obj.catch(onRejected)’ and internally we actually call ‘obj.then(undefined, onRejected)’)
The ‘Promise.prototype.catch()’ method is an alias for.then(null, rejection) or.then(undefined, rejection), and is used to specify the callback function when an error occurs.
1 | catch (onRejected) { |
the implement of ‘finally’ method
The ‘finally()’ method is used to specify an operation that will be performed regardless of the final state of the Promise object. This method was introduced as standard by ES2018.
Regardless of the last state of the promise, the callback function specified by the ‘finally’ method will be executed after the callback function specified by ‘then’ or ‘catch’ has been executed
1 | finally(callback) { |
the implement of ‘all’ method
The ‘promise.all ()’ method is used to wrap multiple Promise instances into a new Promise instance.
1 | const p = Promise.all([p1, p2, p3]); |
The ‘promise.all ()’ method takes an array as an argument. ‘p1’, ‘p2’, and ‘p3’ are all Promise instances; if they are not, the ‘promise.resolve’ method, described below, is called first, turning the argument into a Promise instance, and then further processing. In addition, the ‘promise.all ()’ method may not take an array argument, but it must have an Iterator interface, and each member returned must be a Promise instance.
The state of ‘p’ is determined by ‘p1’, ‘p2’, and ‘p3’, and is divided into two cases.
(1)Only the states of ‘p1’, ‘p2’, and ‘p3’ will become ‘fulfilled’, and the state of ‘p’ will become ‘fulfilled’, at which time the return values of ‘p1’, ‘p2’, and ‘p3’ will be composed of an array and passed to the callback function of ‘p’.
(2)As long as one of ‘p1’, ‘p2’, ‘p3’ is’ rejected ‘, the state of ‘p’ becomes’ rejected ‘, and the return value of the first ‘rejected’ instance is passed to the callback function of ‘p’.
1 | all(promises) { |
the implement of ‘race’ method
Like the ‘all’ method, the ‘promise.race ()’ method wraps multiple Promise instances into a new Promise instance.
1 | const p = Promise.race([p1, p2, p3]); |
As soon as one instance of ‘p1’, ‘p2’, ‘p3’ changes state first, the state of ‘p’ changes. The return value of the Promise instance that changes first is passed to p’s callback function.
1 | race(promises) { |
the implement of ‘allSettled’ method
[ES2020] (https://github.com/tc39/proposal-promise-allSettled) introduced Promise. AllSettled
() method, is used to determine whether a group of asynchronous operations are all over (no matter succeed or fail). That is why it is called “Settled,” which contains both “fulfilled” and “rejected.”
The ‘promise.allsettled ()’ method takes an array as an argument, each member of which is a Promise object, and returns a new Promise object. The state of the returned Promise will not change until all the Promise objects in the parameter array have changed (either ‘fulfilled’ or ‘rejected’).
1 | static allSettled(promises) { |
the implement of ‘any’ method
ES2021 introduced [Promise. Any ()
method] (https://github.com/tc39/proposal-promise-any). This method takes a set of Promise instances as an argument and returns it wrapped as a new Promise instance.
As long as one of the parameter instances becomes’ fulfilled ‘, the wrapper instance will become ‘fulfilled’. If all the parameter instances become ‘rejected’, the packaging instances become ‘rejected’.
‘Promise.any()’ is very similar to the ‘promise.race ()’ method, except that ‘promise.any ()’ does not end when a Promise becomes’ rejected ‘. It must wait until all arguments Promise change to the ‘rejected’ state.
The error thrown by ‘Promise.any()’ is an AggregateError instance, and the errors property of the AggregateError instance object is an array containing all the errors of its members.
1 | any(promises) { |