Content provider: Jinniu District Wudi Software Development Studio

I was looking at some other big guy’s blog and saw articles about setTimeout, promise, and async execution order. After watching several articles, I still didn’t understand much, so I started to analyze the code myself and organized this article. I believe that through this article, friends can understand asynchronous synchronization and setTimeout,Promise,async clearly. Next, let’s get to the main topic:


Here’s the code from another big guy’s blog:

async function async1() {
   console.log('async1 start')
   await async2()
   console.log('async1 end')}async function async2() {
   console.log('async2')}console.log('script start')
setTimeout(() = > {
	console.log('setTimeout')},0)
async1()
new Promise((resolve) = > {
	console.log('promise1')
	resolve()
}).then(() = > {
	console.log('promise2')})console.log('script end')
Copy the code

Execution results (different browsers may have different results, I used Google) :

PS: The following key points are circled in bold for friends, please watch carefully

At this time, the author turned on the two-screen mode, looked at the result of the code to guess its rules, and then looked at the MDN document, the result is clear at a glance.Let’s now analyze the code: This only defines two asynchronous functions (), which are not called, so don’t worry about them for now.

This is synchronous, so it will be executed directly

1. Run script start

SetTimeout is a timer, asynchronous, and therefore thrown into the task queueWe just need to remember that it’s in the asynchronous queue.

If async1 is called, it will go into this function. Let’s look at this function again:PS: Note that async returns a Promise object when called. The Promise object is executed immediately, as described later.

This time will be

2. Output async1 start

“Await async” (” await c2 “) will cause async function to suspend execution. “await” (” await “) will cause the following content to be added to the browser task queue. So here async1 start is printed and

Async2 is output

Async2 returns to async1. Throw unexecuted parts of async1 into the task queue. (Now the task queue has a setTimeout and an async1 successor)

Then came the Promise: Promises are implemented immediatelySo it will immediately

4. Output promise1.

Resolve is then executed. If it succeeds, it goes into the promise’s.then method, but it’s an asynchronous callback, so it gets thrown into the task queue. (Now the task queue has a setTimeout and an async1 subsequent to the promise’s. Then content)

Finally came:Because it is synchronous, it is executed directly.

5. Output: script end

With the first five analyzed, we come to the key point: there are now three tasks in the asynchronous queue:

  • setTimeout
  • Next to Async1
  • Promise’s.then content

SetTimeout will execute at the end, just like the priority of CSS weights, which you can always remember. SetTimeout is not as high as async and Promise. The async method returns a promise object) and then the async and the promise then depend on who is the first to enter the task queue, which has a first-in, first-out concept. So the result is obvious, the output order of the three is: 6. Output: async1 end 7. 8. Output: setTimeout

Write a random code for your friends and guess what the result will be:
setTimeout(() = > {
	console.log('setTimeout')},0)
console.log('t1')
fetch('http://dict.qq.com')
 .then(function(response) {
   return response.json();
 })
 .then(function(myJson) {
   console.log('myJson');
 })
 .catch(function(err) {
 	console.log(err)
 })
console.log('fetch zhi hou')
async function async1() {
	console.log('async1 start')
	await async2()
	console.log('async1 end')
}
async1()
console.log('t2')
new Promise((resolve) = > {
	console.log('promise')
	resolve()
}).then(() = > {
	console.log('promise.then')})console.log('t3')
async function async2() {
	console.log('async2')}console.log('t4')
Copy the code

Execution Result:

Summary:

This is actually an Event Loop that involves JavaScript.This is the whole JS event loop.

Execute global Script synchronization code, some of which are synchronous statements, some of which are asynchronous statements (setTimeout, etc.); After executing the global Script code, the call Stack is emptied; Remove the callback task at the beginning of the microtask queue from the microtask queue and put it into the call Stack for execution. After execution, the length of the MicroTask queue decreases by 1. Continue fetching the task at the top of the queue, place it on the call Stack, and so on until all the tasks in the MicroTask Queue have been executed. Note that if a microtask is created in the process of executing it, it is added to the end of the queue and executed during this cycle. When all tasks in the MicroTask Queue are completed, the MicroTask Queue is empty and the call Stack is empty. The task at the head of the microtask queue is displayed in the Stack and executed. After the execution, the call Stack is empty. Repeat steps 3-7; Repeat steps 3-7; .

1. Macro queue MicroTask executes only one task from the queue at a time, and then executes the tasks in the microtask queue.

2. All tasks in the microtask queue are removed and executed until the Microtask queue is empty. 3. There is no UI rendering node because it is at the discretion of the browser, but when UI rendering is performed, the node performs UI render immediately after all the microtasks and before the next MacroTask.