promise is a new method proposed by ES6 to solve asynchronous programming problems.
1. Synchronous and asynchronous
1) Synchronization task: Task 2 cannot be executed until task 1 is executed. Synchronization tasks are directly placed in the main thread.
2) Asynchronous task: asynchronous tasks are placed in the event queue. Asynchronous tasks will be executed only after the synchronous task is completed. Common asynchronous tasks: event listening (click, etc.), callback function (timer, ajax request, some callbacks of nodejs), promise, generator, etc. in ES6, file operation
2. Event loop
Steps:
(1) For all tasks - judge whether it is synchronous
(2) If it is a synchronization task, put it into the main thread and execute it in order
(3) If the task has been queued asynchronously, click "queue" to put the task in the queue. If the task has been queued asynchronously, it will be placed in the queue.
(4) When all the tasks of the main thread are completed, check whether there are tasks in the event queue. If there are tasks, take them to the main thread for execution.
3. promise realizes asynchronous programming
3.1 what is promise
Abstract understanding:
1) promise is a new technology proposed by ES
2) promise is a new solution for asynchronous programming in js (old operation: using callback function)
Specific expression
1) Syntactically, promise is a constructor
2) Functionally speaking, promise object is used to encapsulate an asynchronous operation and obtain the value of success / failure results.
3.2 why use promise
Using promise's chain call can solve the callback problem
1) Callback Hell: callback functions are nested. The result of asynchronous execution of external callback functions is the condition of nested callback functions.
2) Disadvantages of callback Hell: it is not easy to read and handle exceptions
3) Solving callback Hell: chain call of promise
More flexible way to specify callback function
1) Old: the callback function must be specified before restarting the task
2) Promise: start asynchronous task = > return promise object = > bind callback function to promise (multiple can be specified)
3.3 promise status - attribute of instance object
Three states of promise object
1) Initialization (waiting) status pending
2) Status of successful request: fully / resolved
3) Status of request failure rejected
Note: the state of promise can change from pending to success or failure, but it cannot be changed after changing to success or failure, and the change of state is irreversible.
3.4 promise object value -- the attribute of the instance object (promise result)
Holds the success / failure values of asynchronous tasks
resolve and reject can change the value of this attribute. err is the value of failure and data is the value of success
const p = new Promise(function (resolve, reject) {
fs.readFile("for learning. md", (err, data) = >{
if (err) {/ / if the status is failed, call the failed callback function
reject(err);
}else {/ / the status is success. Call the successful callback function
resolve(data.toString());
}
4. API of promise
4.1 promise constructor
4.1.1 use steps
1) establish promise object new Promise(parameter) ,Wait status //This procedure is called synchronously 2) promise The parameter of the object is an executor function. The modified function has two parameters (callback function), i.e new Promise(function(resolve,reject)); reslove The callback function is the callback function that needs to be called when the execution is successful, and the status changes to success, reject Is the callback function to be called when the execution fails, and the status is changed to failed. 3) adopt promise.then()and promise.catch()Method for capturing promise The status of success or failure, and process the returned results.
Asynchronous operation to read files // promise read file // 1. Introduce fs module const fs = require("fs"); // 2. Calling the method err returns an error, and data is the read data // Reading a file is an asynchronous operation const p = new Promise(function (resolve, reject) { fs.readFile("engage in study.md", (err, data) => { if (err) {//If the status is failed, call the failed callback function reject(err); } else { //If the status is success, call the successful callback function resolve(data.toString()); } }); }); //Call the then method of the promise object //The first callback function corresponds to resolve and the second callback function corresponds to reject p.then( function (value) { console.log(value); }, function (reason) { console.log(reason); } );
4.1.2 then () method and catch() method -- specify callback
The difference between the two
promise.then (function (P1) {}, function (P2) {}) the first function captures the status of successful execution, and the second function captures the status of failed execution.
promise.catch() is the processing of the result of execution failure, which is equivalent to the second function operation of then
promise.then method
- The function is executed only if the state changes
- promise. The return value type of then () is still promise
/call promise Object then method //The first callback function corresponds to resolve and the second callback function corresponds to reject p.then( function (value) { console.log(value); }, function (reason) { console.log(reason); } );
promise.then() can write only one callback function
p.then(value=>{ console.log(value); }) 3. because promise The return value of is still promise,So you can chain callback to avoid callback hell p.then(value=>{ console.log(value); }).then(value=>{ console.log(value); })
promise.catch() method
Used to specify the callback for promise failure, which is equivalent to the second function of the then () method
const fs = require("fs"); // 2. Calling the method err returns an error, and data is the read data // Reading a file is an asynchronous operation const p = new Promise(function (resolve, reject) { fs.readFile("engage in study.md", (err, data) => { reject(err); }); }); p.catch(function(value){ log('error')//Corresponding receive reject })
5 Promise object method
5.1 Promise.resolve method (value) = > {}
Receive a parameter and return a success or failure promise object
1) The parameters passed in are of non promise type, and the returned results are successful peomise
2) If the result passed in is a promise object, the result of this parameter determines the result of resolve
//Type 1 parameter is of non promsie type let p1 = Promise.resolve(123); console.log(p1); // Type 2 parameter is promise type let p2 = Promise.resolve(new Promise(function(reslove,reject){ reject('error') //The status is error and the result value is error })) console.log(p2);
Type 1 return result
Type 2
5.2 Promise.reject()
After receiving a parameter, all the returned promise objects are failed. Even if a successful promise object is passed in, the returned promise object is also failed. The result of failure is the value passed in.
5.3 Promise.all() method (promise) = > {}
(1) The parameter passed in is an array containing n promise s
(2) A new promise is returned. The success status is returned only when all promises are successful. The result value is an array of success result values of all successful promises. As long as one state fails, it will fail directly. The result value of failure is the result value of the failed promise.
5.4 promise.race method (promises) = > {}
(1) Received parameter promise array
(2) The returned result is a new promise. The first state to complete the promise is the final result state (whoever changes the state first will output the result)
6. Several key issues in promise
6.1. How to change the state of promise
(1) resolve (value) changes the pending status to resolved
(2) reject (reason) change pending to rejected
(3) Throw an exception and change pending to rejected
const p = new Promise(function (resolve, reject) { // reslove('ok') ; // Put pending - "resolved" // reject('error'); // Change pending to rejected //Throw an exception and change pending to rejected throw 'Error ' });
6.2 if a promise specifies multiple successful / failed callback functions, will they be called
Specify the then () method for the callback function
Answer: when promise changes to the corresponding state, it will be called
let p =new Promise(function(resolve,reject){ resolve('ok');//Change status to success }); p.then(function(res){ console.log(res); }) //Specify callback again p.then(res=>{ console.log('Call again'); })
6.3 change the state of promise and specify who will call the function first and then?
That is, resolve()/reject is executed first; Or then ()
(1) It's all possible
Under normal circumstances, the callback is specified first and then the state is changed: when the executor is an asynchronous task (mostly)
However, it is also possible to change the state before specifying a callback
(2) How to change the status before specifying callback
Directly call resolve()/reject() / / synchronization task in the executor
Extend the longer event and call then()
(3) When will we get the data
If the callback is specified first, when the state changes, the callback function will be called and the data will be obtained
When the callback is called, it will get the data first. If the callback is called, it will get the data first
6.4 promise.then() returns the result of the new promise. What determines the status
Determined by the execution result of the callback function specified by then
(1) If an exception is thrown, the state of the new promise is rejected, and the return value reason is the exception thrown
(2) If the return value is any value other than promise, the new promise is resolved and value is the returned value
(3) If another new promise is returned, the status and return value of this promise will become the return result of the new promise
6.5 how promise concatenates multiple operation tasks
(1) The return value of promise is still a promise object. You can use the chain call of then()
(2) Concatenate multiple synchronous / asynchronous tasks through the chain call of then
let p = new Promise((reslove, reject) => { setTimeout(() => { //Asynchronous task reslove('ok') }, 1000); }); p.then(value => { console.log(value); //ok return new Promise((reslove, reject) => { reslove('success'); }) }).then(value => { console.log(value); //success }).then(value => { console.log(value); //undefined }) // The origin of the last undefine. The return value of then is a promise object, // However, the second then does not return and defaults to undefined, that is, the input of the third then is undefined //, undefined does not belong to promise type, so the last returned status is success and the value is undefined
6.6 abnormal penetration of promise
(1) When using promise's then chained call, you can specify the failed callback at the end
(2) Any exception in the previous operation will be transferred to the final callback for processing
p.then(value => { console.log(value); //ok return new Promise((reslove, reject) => { //reslove('success'); reject('erroe') }) }).then(value => { console.log(value); //success }).then(value => { console.log(value); //undefined }).catch(reason=>{ console.log(reason) //Specify only the wrong callback function at the end //If there is an error in then in the middle, this callback function will also be executed })
6.7 terminal promise chain p.then() then()
(1) When the then chain call of promise is used, it is interrupted in the middle and the callback function behind it is no longer called
(2) Method: return a promise object in pending status in the callback function
p.then(value => { console.log(value); //ok return new Promise((reslove, reject) => { //reslove('success'); reject('erroe') }) }).then(value => { console.log(value); //success // The middle promise chain is a promise object in pending status reruturn new Promise(()=>{}) }).then(value => { console.log(value); //undefined }).catch(reason=>{ console.log(reason) //Specify only the wrong callback function at the end //If there is an error in then in the middle, this callback function will also be executed })
7. async function
(1) The return value of the function is the promise object
If the return value is a non promise type, the result is a successful promise
If the return value is a promise object, it determines the return result of the async function
If an exception is thrown, the status of the returned result is failed and the value is the thrown value
async function main(){ //retrun '521' / / the first type return new Promise((resolve,reject)=>{ resolve('ok) //The second type }) //return throw 'error' / / the third type }
(2) The result of the promise object is determined by the return value of the async function
8. await expression
(1) The right side of await is generally a promise object, which can also be other values
(2) If the expression is a promise object, the return value of await is the value of promise success
(3) If the expression is another value, its value is directly used as the return value of await
(4) await must be written in the async function, but it can not be in the async function
(5) If the promise of await fails, an exception will be thrown, try.. catch exception handling
async function main() { let p = new Promise((resolve, reject)=>{ // resolve('ok'); reject('error'); }); // let res = await p; // console.log(res); try { let res2 = await p; } catch (e) { console.log(e); } }
Note source:
https://www.bilibili.com/video/BV1GA411x7z1?p=45&spm_id_from=pageDriver