I knew the names of async and awiat a long time ago, but I've always been lukewarm about this thing;
Recently, when I was doing koa, a lot of async and await bothered me a little;
I'll spend half a day alone to solve the whole async and await
Some children's shoes may know that they are extended based on promise of es6;
Before explaining, let's talk about the history of the origin of promise; Although it's a little nonsense, it's helpful to help you understand async
1. History of promise
You may encounter such an interview. What is promise? What is his purpose
Many children's shoes may say that they are to solve the problem of callback hell. When the problem comes, can you talk about what callback hell is in detail;
Of course, this problem is not a problem for some powerful children's shoes,
Here I want to talk about another reason for his origin
A long time ago
If we have an asynchronous function inside a function, how can we get the variables in the asynchronous function
Maybe the quick children's shoes are return ed directly in the asynchronous function, but can you really get them?
function test(){ setTimeout(()=>{ return "hello world" },1000) } console.log(text()) // undefined
The above reason is that the internal execution of the function is completed immediately and does not wait for the execution of the asynchronous function to be completed. In the synchronous block, nothing is returned. Of course, printing is undefined
How do we get the variables executed in asynchronous
//The previous programmer's solution was to use callback functions
function test(callback){ setTimeout(()=>{ callback("hello world") },1000) } test(function(msg){console.log(msg);});
The above procedure can actually be regarded as the following situation
function test(callback){ setTimeout(()=>{ callback("hello world") },1000) } var callback=function(msg){ console.log(msg) } test(callback)
But the problem is that if you want to be so simple in your work, you'd better know that you often have to communicate with the server through ajax
But let's just communicate. Often, the parameters of the next ajax communication depend on the results of the previous ajax communication
This leads to the nesting problem. Sometimes it is not enough to set one layer, but several layers, which leads to the problem of callback hell
At this time promise was born
Here we use promise to modify the above program
function test(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve("hello world"); },1000) }) } test().then(res=>{console.log(res)}) // Output hello world
Does it look like that
A new promise function is returned inside the function body
After the function is executed, there is a. then method to receive the internal information of successful execution
We can put variables in resolve() as parameters in. then to receive them
But promise, I won't talk about it in detail here. You can go and see Mr. Ruan Yifeng's es6
2.async and await
Don't talk about async and await as a new knowledge until you learn it
He was just something we had learned before. He put on a new layer of clothes. First of all, he was not afraid of him
Officials explain a lot of professional terms, so don't read it. The more you see it, the more confused you become
The popular explanation is to make your asynchronous code look more like synchronization. Don't think too much of it
I'll give you a few examples in turn, and you may understand
1. After adding async to the function, the function returns a promise object
async function test(){ console.log(111); } console.log(test());
If no data is returned in the function, there is an undefined after promise
2. Function with return value
async function test(){ return "111"; } console.log(test());
How do we get the return value
Smart children's shoes may think that since they are promise objects, take them in the way of promise
bingo clever!
async function test(){ return "111"; } test().then(res=>{console.log(res)}); // Output 111
3. Before await keyword, don't treat sync as asynchronous. As long as it's not asynchronous code and synchronous belt, do you treat it equally
Just follow the normal order
async function test(){ console.log(111); } test(); console.log(2222);
4.await keyword
Remember that await must only be in the function body with async in front, otherwise an error will be reported
Here is an example of a normal point
Here, you can pause and know the children's shoes of await. You can mark the following output order first
function func(){ return new Promise((resolve)=>{ setTimeout(()=>{ console.log(111); resolve('222'); },3000) }) } async function test(){ var n=await func(); console.log(n); console.log(333); } test(); console.log(444); // Answer: 1.444 2.111 3.222 4.333
This await has to be explained
There are two kinds of function objects to wait after await: 1. Return promise; 2. Do not return promise
Before the two, it is divided into whether to return synchronous or asynchronous. Whether there is a return value is explained below
A very important point is that no matter what the above situation is, await will block the execution of the following code
4.1 first, let's talk about the function object that does not return promise, and the code is synchronized, and there is no return value
//await will block the following code execution. First execute the synchronization code outside the function
Therefore, the following output order is 111 333 222
function func(){ console.log(111); } async function test(){ await func(); console.log(222); } test(); console.log(333);
4.2 await does not return the function object of promise object, and it is synchronous, and the code has a return value
await is the code executed from right to left. After the function on the left is executed, the return value is copied to n
The execution order of the following code is 333 111 222
function func(){ return "111"; } async function test(){ var n=await func(); console.log(n); console.log(222); } test(); console.log(333);
4.3 await does not return the function object of promise object, and the code is asynchronous and has no return value
Keep in mind that await will block the execution of subsequent code, and execute the external synchronization code first
The execution order of the following functions is 111 444 333 222
function func(){ console.log(111); setTimeout(()=>{ console.log(222); },1000) } async function test(){ await func(); console.log(333); } test(); console.log(444);
Some children's shoes here may wonder if they don't block the execution of the following code and execute the functions after await first
It's really finished here. I see that 111 is printed first
However, there is an asynchronous function behind it, which naturally enters the asynchronous event queue and waits for the scheduled event to be executed after it is completed
So now the 333 behind the natural family will be implemented
awati makes the code look synchronous. It doesn't make the code go synchronous and blocked
4.4 await does not return the function object of promise object, and it is asynchronous. The code has a return value (confusing)
The following output is / / 111 444 undefined 333
After func is executed, there is no return value. Naturally, it is correct. It is undefined
The func function that says there is a return value in other people's asynchronous functions has been executed, and this value cannot be obtained outside
If you want to get it, look at the promise below
function func(){ console.log(111); setTimeout(()=>{ return "222"; },1000) } async function test(){ var n=await func(); console.log(n); console.log(333); } test(); console.log(444);
4.5 await returns the function object of promise object, and it is not asynchronous. The code has no return value
The order of output here is 111 333
Here may wonder why there is no 222
Remember that if you return a promise object, there is no return value
await won't execute the following code if it can't wait for the return value. Remember this, children's shoes
function func(){ return new Promise((resolve,reject)=>{ console.log(111); }) } async function test(){ await func(); console.log(222); } test(); console.log(333);
4.6 await returns the function object of promise object, and the code is asynchronous and has no return value
//The output order of the following code is 333 111
Similarly, if the return value is not received, the following console.log(222) will not be executed directly
function func(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ console.log(111); },100) }) } async function test(){ await func(); console.log(222); } test(); console.log(333);
4.7 await returns the function object of promise object, and it is not asynchronous. The code has a return value
//The following execution sequence is 111 444 222 333
function func(){ return new Promise((resolve,reject)=>{ console.log(111); resolve(222); }) } async function test(){ var n=await func(); console.log(n); console.log(333); } test(); console.log(444);
4.8 await returns the function object of promise object, which is asynchronous, and the code has a return value
The execution order of the following code is 111 444 222 333
await knows that the return is promise, and it needs to get the returned value assigned to n, so it is the order of printing
function func(){ return new Promise((resolve,reject)=>{ console.log(111); setTimeout(()=>{ resolve(222); },1000) }) } async function test(){ var n=await func(); console.log(n); console.log(333); } test(); console.log(444);
That should be clear
Finally, a classic interview question to async and await is attached
async function async1(){ console.log('async1 start') await async2() console.log('async1 end') } async function async2(){ console.log('async2') } console.log('script start'); setTimeout(function(){ console.log('setTimeout') },0) async1(); new Promise(function(resolve){ console.log('promise1') resolve(); }).then(function(){ console.log('promise2') }) console.log('script end')