Promise is the solution to asynchronous task synchronization? This article introduces Promise through the following aspects:
- What problem did Promise come along to solve
- Internal processing of a task within a Promise
- The standard specification for Promises
- Use the Promise method
- The Promise executes the order in the eventLoop
- The source address
Promise knowledge is divided into five chapters. In this chapter, we discuss the use of Promise methods. In front of us, we talked about the problems that Promise solves, including a variety of states and standard specifications within Promise. When these internal principles and functions are understood, we will talk about what APIS and methods Promise provides to developers. This is also the most commonly used and most down-to-earth section of our development. Let’s take a look at all of Promise’s methods:
Instance methods:then()
.catch()
.finally()
.
Static (attribute) methods:all()
.race()
.resolve()
.reject()
, new ES2021 featuresany()
.
Instance methods
Instance methods are methods that can be invoked by instantiation, that is, by saying new Promise(). The instance method is mounted on the Prototype of the Promise constructor. One step in the new process is to point the constructor’s prototype to the __proto__ of the newly created object. So the new object returned can be found and called along the scope chain.
then()
The then() method returns a Promise. It needs at most two arguments: a callback to Promise’s success and failure cases.
const p = new Promise((resolve, reject) = > {
resolve('Success! ');
});
promise1.then(value= > {
console.log(value);
},reason= >{
console.log(reason);
});
// expected output: "Success!"
Copy the code
Parameter 1, P. Teng (onFulfilled,onRejected); Then receives two non-mandatory function parameters, onFulfilled success state and onRejected failure state, which corresponds to resolve() and reject() in the Promise respectively. 2. The pass parameter in the function is the value passed from Promise. If the. Then parameter is not a function, processing of the state will be abandoned internally, but no error will be generated. This is a big pity. (‘_’,season=>{}) Then also returns a Promise object with the state and value of the previous Promise.
let p = new Promise((resolve, reject) = > {
resolve(2)})let a = p.then('_'.'_')
a.then((value) = > {
console.log(value);
})
// expected output: "2"
Copy the code
4. Of course, the return result of THEN is determined by the callback function in THEN. This is very depressing. For example, p.teng (value=>{return XXX}) is Fulfilled when P is Fulfilled. There are three scenarios:
- The callback throws an exception,
.then
So does the returned Promise objectrejected
.
let p = new Promise((resolve, reject) = > {
resolve(2)})let result = p.then((value) = > {
throw 'There's a problem.'
}, err= >{})console.log(result)
/* Expected output: Promise {
} __proto__: Promise [[PromiseStatus]]: "Rejected" [[PromiseValue]]: "Failed" */
Copy the code
- The callback returns a non-Promise object,
.then
Returns a Promise with a success status and the result is the return value.
let p = new Promise((resolve, reject) = > {
resolve(2)})let result = p.then((value) = > {
return '123'
}, err= >{})console.log(result)
/* expected output: Promise {
} __proto__: Promise [[PromiseStatus]]: "resolved" [[PromiseValue]]: "123" */
Copy the code
- The result of the callback is the Promise object,
.then
The returned Promise is a callback that returns the state and result of the Promise.
let p = new Promise((resolve, reject) = > {
resolve(2)})let result = p.then((value) = > {
return new Promise((resolve, reject) = > {
reject('failure')})},err= >{})console.log(result)
/* Expected output: Promise {
} __proto__: Promise [[PromiseStatus]]: "Rejected" [[PromiseValue]]: "failed" */
Copy the code
catch()
The catch() method returns a Promise, a function argument, that is a failed state callback. This is the same method as the second argument to THEN (), which calls the then() callback to onRejected.
// The first case:Errors thrown in asynchronous functions are notcatchOr then() the second argument is caughtvar p1 = new Promise(function(resolve, reject) {
setTimeout(function() {
throw 'Uncaught Exception! ';
}, 1000);
});
p1.catch(function(e) {
console.log(e); // Will not be executed
});
// The second case:Once the state becomes successful, it continues backward but cannot catch errors, in line with the principle that once the state is determined, it cannot be changedvar p2 = new Promise(function(resolve, reject) {
resolve()
throw 'Uncaught Exception! ';
});
p2.catch(function(e) {
console.log(e); // Will not be executed
});
Copy the code
var p = new Promise(function (resolve, reject) {
reject(2)}); p2.catch(() = > { console.log(1); })
.then(() = > { console.log(2)},() = > { console.log(3); });
//expected output: 1 2
Copy the code
finally()
The samefinally()
Also returns a Promise, with a function argument, but no Promise value in this callback, regardlessIt will be called with or without successJust do the same thing to some things in the callback after the operation is done.
For example, before a request is made, we need to start loading. After the request is completed, whether it fails or not, we need to stop loadingfinally()
In the execution.
Now, one more point that’s worth noting
Due to thethen
The callback in the method is no morereturn
Worth it, so hisPromiseValue
forundefined
.
而finally
The method returns the Promise result by default.
Static (property) methods
resolve()
.reject()
Resolve () is explained in detail in Chapter 3 when we discuss state determination methods. The four states that pass values return Promise objects of different states. Resolve (), reject() are also grammatical sugars
new Promise((resolve, reject) = > resolve('success')).then(() = >{},() = >{}) is equivalent toPromise.resolve('success').then(() = >{},() = >{})new Promise((resolve, reject) = > reject('fail')).then(() = >{},() = >{}) is equivalent toPromise.reject('fail').then(() = >{},() = >{})Copy the code
all()
Promise.all(), returns an instance of Promise that will receive an iterable type (Array,Map,Set). If the state is fulfilled, then() will callback successfully with an Array. Inside is the resolve value of the iterable result.
const p1 = Promise.resolve(3);
const p2 = 42;
const p3 = new Promise((resolve, reject) = > {
setTimeout(resolve, 2000.'foo');
});
Promise.all([p1, p2, p3]).then(values= >console.log(values));
// Expected output: 2 seconds later [3, 42, "foo"]
Copy the code
1. The All () method waits for all Promise objects to change state to resolve before firing the then() method.
const p1 = Promise.reject(3);
const p2 = 42;
const p3 = new Promise((resolve, reject) = > {
setTimeout(reject, 2000.'foo');
});
Promise.all([p1, p2, p3]).then(values= > console.log(values),(err) = >console.log('err', err));
// Expected output: Indicates that err 3 will be output immediately
Promise.all([p3, p2, p1]).then(values= > console.log(values),(err) = >console.log('err', err));
// Expected output: Indicates that err 2 will be output immediately
Copy the code
2. The onRejcted function in then() will be called as soon as a Promise in the all() method changes to Rejected. Even if there is multiple Reject, only the earliest rejected state is suggested. This raises the question, is the Promise passed in called synchronously or asynchronously?
const p1 = new Promise((resolve, reject) = > {
setTimeout(resolve, 4000.'foo');
});
const p2 = 42;
const p3 = new Promise((resolve, reject) = > {
setTimeout(resolve, 2000.'foo');
});
Promise.all([p1, p2, p3]).then(values= >console.log(values));
["foo", 13, "foo"]
Copy the code
Let’s take a look at a few scenarios of his state:
var resolvedPromisesArray = [Promise.resolve(33), Promise.resolve(44)];
var p = Promise.all(resolvedPromisesArray);
console.log(p);
setTimeout(function(){
console.log('next tick');
console.log(p);
});
// Promise { <state>: "pending" }
// next tick
// Promise { <state>: "fulfilled", <value>: Array[2] }
Copy the code
1. If a set of promises is passed in, state execution is asynchronous. The state of P in the current cycle will not immediately become depressing. The same to reject
var p = Promise.all([]);
var p2 = Promise.all([123."hello"]);
console.log(p);
console.log(p2)
setTimeout(function(){
console.log('next tick');
console.log(p2);
});
// Promise { <state>: "fulfilled", <value>: Array[0] }
// Promise { <state>: "pending" }
// next tick
// Promise { <state>: "fulfilled", <value>: Array[2] }
Copy the code
2. When an empty iterable is passed, the state changes synchronously and immediately.
race()
The race() method differs from all() in that the onResolve callback to THEN () does not take an array of arguments and passes multiple promises, but ultimately returns the Promise that completes first. The callback in then() also corresponds to the state of this Promise.
const p1 = new Promise((resolve, reject) = > {
setTimeout(resolve, 500.'p1 success');
});
const p2 = new Promise((resolve, reject) = > {
setTimeout(resolve, 100.'p2 success');
});
Promise.race([p1, p2]).then((value) = > {
console.log(value);
});
// expected output: "p2 success"
Copy the code
any()
This method is still experimental (September 2021) and not supported by all browsers. Return a Promise object, and the argument also passes an iterable set. 1. If one of the promises succeeds, the successful promise is returned and terminated. 2. If all promises fail, then() will be onFulfilled.
If this article can help or inspire you, it will be my pleasure