This article is for those of you who want to get to know promises. It’s about the basics of promises, but nothing too difficult to understand.
I first met Promise
1.1 What is Promise
Promise: a new built-in class in ES6 (think new, prototype, prototype chain, instance…) , based on promise can effectively manage asynchronous programming in JS, and solve the problem of “callback hell” caused by traditional asynchronous programming + callback function. => We call asynchronous control based on promises the ‘Promise design pattern’
1.2 Learn what Promise needs to master
Start with functions that have three roles: ordinary functions, constructors (classes), and ordinary objects
Normal object => static private property method
- promise.all()
- promise.race()
- promise.resolve()
- promise.reject()
Class => Common properties and methods on the stereotype chain
- promise.prototype.then()
- promise.prototype.catch()
- Promise. Prototype. Finally () [no] generally
γnew create instance γ
Create a Promise instance
2.1 Syntax for creating Promise instances
Let instance = new Promise([executor])
Description:
- Uncaught TypeError: Promise resolver undefined is not a function
[executor]
Is a function where we normally manage our asynchronous programming codenew Promise
When you get thereexecutor
Executed immediately- And give
executor
The function passes two arguments (both of which are also functions) :resolve/reject
let p1 = new Promise(a);Uncaught TypeError: Promise resolver undefined is not a function
let p2 = new Promise((resolve,reject) = >{
// Asynchronous programming code
});
Copy the code
2.2 Two values of Promise
An instance of a Promise has [[PromiseStatus]]/[[PromiseValue]]
[[PromiseStatus]] is a promise state (either success or failure)
- readiness
pending
:new Promise
The default state ispending
- The successful state
fulfilled/resolved
: Usually after an asynchronous operation succeeds, we pass the executionresolved
The delta function, we can take the delta functionpromise
Change the state ofresolved
- The failure state
rejected
: Usually after an asynchronous operation fails, we pass the executionreject
The delta function, we can take the delta functionpromise
Change the state ofrejected
Pending => Resolved/Rejected Once the status is changed, it cannot be changed
[[PromiseValue]] is the promise value
- Whether to perform
resolve/reject
Any function can pass a value, and the value passed can be assigned to[[PromiseValue]]
For example, we created a Promise instance P1, and when we created it we put the Resolved function in the function and put it in the successful state
let p1 = new Promise((resolve, reject) = > {
setTimeout((a)= > {
resolve('ok');
console.log(p1) //=>'resolve' 'ok'
}, 1000)
}); console.log(p1); //=>'padding' undefined Copy the code
2.3 Summary: What you do when you create an instance
We’re creating an instance of a Promise, and we need to pass the Promise a function that executes immediately and the browser gives it two arguments (both of which are functions) that change the state and value of the Promise
The common method on the Promise prototype chain -then
3.1 What is then
We can change the state of a Promise when creating an instance, in order to control which of the two methods in then executes. Then ([executed on success of state], [executed on failure of state])
result / reason
Receive is[[PromiseValue]]
Information (inexecutor
Function, based onresolve/reject
To execute the passed value is to givepromise-value
Can only pass one value. Passing the second argument is useless.
let p1 = new Promise((resolve, reject) = > {
setTimeout((a)= > {
if (Math.random() < 0.5) {
reject('NO');
} else {
resolve('OK'); } }, 1000); }); p1.then(result= > { console.log(` success:${result}`); }, reason => { console.log(` failure:${reason}`); Reject (reject) {reject (reject); reject (reject) {reject (reject); reject (reject) }); Copy the code
3.2 When is the THEN method executed?
1. Create an instance and execute asynchronous code:
- Asynchronous requests are placed in
EXECUTOR
In, what to do if the request succeeds or failsTHEN
In the
2. Create instances that execute non-asynchronous code:
EXECUTOR
Functions in theory control asynchronous programming code, but in development, you can do whatever you want; But no matter what you do,THEN
The method in thePROMISE
The command is executed only when the status changes to successful or failed.- in
EXECUTOR
Execute in functionRESOLVE
orREJECT
, not necessarily immediatelyTHEN
Method execution; If, before these two functions are executed, theTHEN
If the successful or failed method is placed, it is immediately notified to execute; If you haven’t done it yetTHEN
Methods need to waitTHEN
After execution, the method is placed, and the successful or failed method is notified to execute!
new Promise((resolve, reject) = > {
// Asynchronous requests are placed in EXECUTOR, and what is done after the request succeeds or fails is written in THEN
$.ajax({
url: '/api/info'. method: 'get'. success: result= > { resolve(result); }, error: reject }); }).then(result= > { }, reason => { }); Copy the code
new Promise((resolve, reject) = > {
reject(100);
}).then(result= > {
console.log(` success:${result}`);
}, reason => {
console.log(` failure:${reason}`); }); Copy the code
3.3 Return value of the then method
Each execution of. Then returns a new Promise instance (initial state: Pending initial value: undefined). So we can keep going. Then going, that’s the then chain mechanism in promises
The following example shows that the success or failure status of the p2 instance is determined by the p1.then pile of code
- Case one: as long as
p1.then
No matter which method executes in,As long as no errors are reported, the state of the new P2 instance changes toSuccessful state, and the result returned by the method is p2 instancepromise-value
Value (that is, the previous onethen
The result of the execution is passed to the nextthen
Method); Similarly, between the two methods,No matter which execution fails, P2 must be in the failed state - Second case: if
p1.then
Executes a method in, returns a newPromise
Instance, will wait for thisPromise
As the execution status of P2
let p1 = new Promise((resolve, reject) = > {
setTimeout((a)= > {
if (Math.random() < 0.5) {
reject('NO');
} else {
resolve('OK'); } }, 1000); }); let p2 = p1.then(result= >{ },reason=>{ }); console.log(p2); let p3 = p2.then(result= > { console.log(result); //=>'OK@@' // return Promise.resolve(100); //=>P3 changes to successful and the value is 100 return Promise.reject(0); //=>P3 changes to failed and the value is 0 }, reason => { }); p3.then(result= > { console.log('success' + result); }, reason => { console.log('failure' + reason); }); Copy the code
3.4 Understanding of THEN chains
The following code output result: understand this code will then master almost (chain is a little long π, don’t worry, the following with a note π)
new Promise(resolve= > {
setTimeout((a)= > {
resolve(10); // After 1000MS, the first PROMISE instance state is success VALUE:10
}, 1000);
}).then(result= > {
console.log(` success:${result}`); / / = > 'success: 10' return result * n; // ReferenceError: n is not defined, that is, let the THEN return PROMISE instance become failed, VALUE: failure reason }, reason => { console.log(` failure:${reason}`); return reason * 10; }).then(result= > { console.log(` success:${result}`); return result * 20; }, reason => { console.log(` failure:${reason}`); //=> ReferenceError: n is not defined' return reason * 10; //NaN code executes without error so that the current THEN returns the instance status: success VALUE: NaN }).then(result= > { console.log(` success:${result}`); //=>' Success: NaN' return result * 20; //NaN code executes without error so that the current THEN returns the instance status: success VALUE: NaN }, reason => { console.log(` failure:${reason}`); return reason * 10; }).then(result= > { console.log(` success:${result}`); //=>' Success: NaN' return Promise.reject(result * 20); // The RETURN of a new failed PROMISE instance affects the state and result of the RETURN. }, reason => { console.log(` failure:${reason}`); return Promise.resolve(reason * 10); }).then(result= > { console.log(` success:${result}`); }, reason => { console.log(` failure:${reason}`); //=>' failed: NaN' }); Copy the code
3.5 then only one method is written
If only one method is set in THEN, the method that succeeds or fails to execute is not set, and the search is carried out in the next THEN. For example, the search is carried out in the current state.
For example, if reason is set, what does it do by default when it needs to be executed? Return promise.reject (reason); return promise.reject (reason); return promise.reject (reason);
π, the code π (the heart is to reject, because it will certainly be a long then chain)
new Promise((resolve, reject) = > {
setTimeout((a)= > {
reject(10); // Status: Failed value :10
}, 1000);
}).then(result= > {
console.log(` success:${result}`); return result * 10; }).then(result= > { console.log(` success:${result}`); return result * 10; }).then(null, reason => { console.log(` failure:${reason}`); / / = > 'failed: 10' return reason * 2; // The code executes without error, leaving the current instance status: success value :20 }).then(null,reason => { console.log(` failure:${reason}`); return reason * 2; }).then(result= > { console.log(` success:${result}`); / / = > 'success: 20' }); Copy the code
Four, Promise. All ()
Promise.all([PROMISE1,PROMISE2,…] ) : Wait for all PROMISE instances to succeed, then the whole will be successful (return a new PROMISE instance), as long as one instance fails, the whole will fail;
function fn1() {
return new Promise(resolve= > {
setTimeout(_= > {
resolve(10);
}, 2000);
}); } function fn2() { return Promise.resolve(20); } function fn3() { return new Promise(resolve= > { setTimeout(_= > { resolve(30); }, 500); }); } Promise.all([fn1(), fn2(), fn3()]).then(results= > { // Execution is triggered only if all three PROMISE instances succeed (as is the one waiting for the latest result), and results stores the results obtained each time, in the order they were placed console.log(results); / / = > [10, 20, 30] }); Copy the code
Fifth, Promise. Race ()
Promise.race() sends multiple requests at the same time, and whoever has the first processing result (whether successful or failed) takes precedence (even if it fails)
Vi. [Supplement] : Exception capture
6.1 Catch means that only one reason method is written in then
In the project, we use CATCH(REASON=>{}) instead of THEN(NULL,REASON=>{}). The effect is exactly the same. (Executing CATCH also returns a new PROMISE instance with a method that was set in the failed state of the instance.)
=> In a project, we usually put “THEN” for successful execution and “CATCH” for failed execution
new Promise((resolve, reject) = > {
setTimeout((a)= > {
reject(10);
}, 1000);
}).then(result= > {
console.log(` success:${result}`); return result * 10; }).catch(reason= > { console.log(` failure:${reason}`); return reason * 2; }); Copy the code
6.2 Exception Catching: Try catch
Why use ittry catch
?
For example, if we print a variable that has never been defined, an error will be reported and the following code will no longer execute, but if we want the following code to continue to execute, we need to use a try catch
console.log(n); //=>Uncaught ReferenceError: n is not defined The browser throws an exception, and the following code will not be executed
console.log('OK');
Copy the code
try catch
try
: places code that might report errors totry
(The console will not throw an exception if an error is reported during code execution, which will not affect subsequent code execution)catch
:catch
Exception information is caught in the
try {
// Put the code in a TRY to catch the exception (the console does not throw an exception once the code is executed)
console.log(n);
} catch (error) {
// CATCH caught an exception (can report the information to the server)
// console.log(error); } console.log('OK'); Copy the code