Problem introduction
What is hell
The case of nested callback functions in callback functions is called callback hell. Callback hell is an operation that occurs to realize the sequential execution of code.
example
setTimeout(()=>{ console.log('This is the first step') setTimeout(()=>{ console.log('This is the second step'); setTimeout(()=>{ console.log('This is the third step'); },1000) },2000) },3000)
There seems to be no problem with the above code, but if the structure of the callback function is very complex, the layer by layer nesting will make the structure of the code unclear.
Problems arising from callback hell
The nesting level is very deep, the readability is poor, and it is difficult to maintain
return and throw cannot be used normally
Unable to retrieve stack information normally
It is difficult to establish a connection between multiple callbacks
Solution to callback hell
1,promise
2,async/await
Promise
What is promise
1. Promise is a native object in js. It is an asynchronous programming solution that can replace the traditional callback function solution.
2. It avoids more callbacks by introducing a callback
In short, Promise is a container that holds the results of an event (usually an asynchronous operation) that will not end in the future. Syntactically speaking, Promise is an object from which you can get the message of asynchronous operation.
promise implementation
Promise has three states: pending, failed and rejected.
new allows you to create a Promise instance object.
Usage:
A. The constructor has two parameters: reloved and rejected, both of which are callback functions
B. Resolved function: changes the state of Promise object from "incomplete" to "successful" (i.e. from Pending to Resolved). It is called when the asynchronous operation is successful, and passes the result of the asynchronous operation as a parameter
C. rejected function: called when the asynchronous operation fails, and passes the error reported by the asynchronous operation as a parameter.
E,. then(): receive the information passed by the reloved function
F,. catch(): receive the information passed by the rejected function
Promise's chain programming can ensure the execution order of the code. The premise is that every time after then is processed, a promise object must be return ed, so that the data can be received in the next then.
function fun(str){ //Create promise object let promise = new Promise((resolve,reject)=>{ var flag = true; setTimeout(()=>{ if(flag){//Simulated asynchronous call succeeded resolve(str);//Deliver the message of success }else{//Failed to simulate asynchronous call reject('error')//Pass out the failed information } }) }) return promise; } fun('This is the first step').then((data)=>{ console.log(data); return fun('This is the second step') }).then((data)=>{ console.log(data); return fun('This is the third step') }).then((data)=>{ console.log(data) }).catch((data)=>{ console.log(data) })
Promise – usage of all
Promise's all method provides the ability to execute asynchronous operations in parallel, and the callback is executed only after all asynchronous operations are executed. Promise All to execute. All receives an array parameter, and the values in it will eventually return the promise object.
function getWidth() { return new Promise((resolve, reject) => { setTimeout(() => { resolve(10) },1000) }) } function getHeight() { return new Promise((resolve, reject) => { setTimeout(() => { resolve(20) },1000) }) } Promise.all([getWidth(),getHeight()]).then((data)=>{ console.log(data); })
Promise – usage of race
As the name suggests, promse A race is a race Which result in race ([F1, F2, F3]) gets faster, it will return that result, regardless of whether the result itself is in the success state or failure state.
function getWidth() { return new Promise((resolve, reject) => { setTimeout(() => { resolve(10) },2000) }) } function getHeight() { return new Promise((resolve, reject) => { setTimeout(() => { resolve(20) },1000) }) } function getLength() { return new Promise((resolve, reject) => { setTimeout(() => { resolve(30) },3000) }) } Promise.race([getWidth(),getHeight(),getLength()]).then((data)=>{ console.log(data); })
async/await
Although Promise has jumped out of the strange circle of asynchronous nesting and expressed it more clearly in chain, we also found that if there are a large number of asynchronous requests and the process is complex, we will find then full of screens, which looks very difficult.
Basic rules for using async/await
The await keyword can only be used in functions defined using async
await can be directly followed by a Promise instance object (any expression can be followed, and more importantly, an expression that returns the Promise object)
The await function cannot be used alone
await can directly get the data in Promise and resolve.
function fun(str){ //Create promise object let promise = new Promise((resolve,reject)=>{ var flag = true; setTimeout(()=>{ if(flag){//Simulated asynchronous call succeeded resolve(str);//Deliver the message of success }else{//Failed to simulate asynchronous call reject('error')//Pass out the failed information } }) }) return promise; } //Encapsulate an async function that performs the above tasks async function test(){ let res1 = await fun('This is the first step')//await gets the promise data returned by the fun function directly let res2 = await fun('This is the second step') let res3 = await fun('This is the third step') console.log(res1,res2,res3); } test();
Capture error
await waits for a promise object, but it doesn't have to write then(..), You can get the return value directly.
since. then(...) don't write, then catch(..) There is no need to write. You can directly catch errors with the standard try... Catch syntax.
function fun(str){ //Create promise object let promise = new Promise((resolve,reject)=>{ var flag = false; setTimeout(()=>{ if(flag){//Simulated asynchronous call succeeded resolve(str);//Deliver the message of success }else{//Failed to simulate asynchronous call reject('error')//Pass out the failed information } }) }) return promise; } async function test(){ try{ let tes = await fun('err') console.log(tes); }catch(err){ console.log(err); } } test();