The JavaScript event execution mechanism includes Tasks queue, MicroTasks queue and call stack. A queue is a first-in, first-out data structure and a stack is a first-in, last-out data structure. The order of execution is global Script-> microtasks (possibly rendering pages) -> macro tasks; Global Script is a synchronous task and is executed only once. Because JavaScript is a single-threaded programming language, asynchronous tasks can only wait for the completion of synchronous task execution.
-
Tasks: contains global Script and macro Tasks; SetTimeout is a macro task
-
MicroTasks: the page may be rendered after each execution of the microtask queue; ** The call stack must be cleared to execute the microtask in the microtask queue; **Promise.then(catch) and obsever are microtasks
Annotated code print: ‘script start’, ‘script end’, ‘promise1’, ‘fail ‘, ‘promise3’, ‘promise2’, ‘promise4’
Uncommented code printing: ‘script start’, ‘script end’, ‘promise1’, ‘promise2’
console.log('script start'); setTimeout(function () { console.log('setTimeout'); }, 0); Promise.resolve() .then(function () { console.log('promise1'); }) .then(function () { console.log('promise2'); }); Resolve ('success').then((res)=>{console.log(res); }).then((res)=>{ console.log('success2'); }); Promise.reject('fail').catch((res)=>{ console.log(res); }); Promise.resolve('success3').then((res)=>{ console.log(res); }).then((res)=>{ console.log('success4'); }); */ console.log('script end');Copy the code
Here’s the uncommented code:
- Execute the code
console.log('script start');
This code enters the global Script task, joins the task queue, adds the global Script task to the queue call stack, and prints’ Script start’.
- Execute the code
setTimeout(function ())
, then the setTimeout macro task is added to the task queue, but the macro task must wait for the completion of the previous round of microtask queue to execute, so the output is still ‘script start’.
- Execute the code
Promise.resolve().then(function ())
Then the microtask must wait for the completion of this round of task queue (global Script/ macro task) before executing, so the output is still ‘Script start’.
- Execute the code
console.log('script end');
Since the global Script task already exists and the call stack is also a global Script, ‘Script start’,’ Script end’ is printed here. At this point, the code has been executed once from top to bottom, indicating that the global Script task is complete. The global Script task is removed
- The call stack was found to be empty. Next, the call stack will add the microtask and execute it, printing ‘script start’, ‘script end’, ‘Promise 1’
- It is found that after executing the above microtask, the microtask is removed from the call stack, and another microtask is called back, so the new microtask is added to the microtask queue, and added to the call stack. After executing the call stack, it prints ‘script start’, ‘script end’, ‘promise 1’, ‘Promise 2’.
- After the execution of the microtask queue is completed, the microtask queue and call stack are removed, and the global Script task is also called. According to the first-in, first-out principle of the queue, the global Script task is removed from the task queue. At this point the page may render once, ready for the next cycle (macro task -> micro task)
- The task queue executes the macro task, and the macro task setTimeout callback function adds the task to the call stack for execution, printing ‘script start’, ‘script end’, ‘PROMISE 1′,’ Promise 2′, ‘setTimeout’. After execution, Remove the macro task from the call stack, find no microtask queue no microtask, so remove the task stack, code execution complete!
Think about:
1. Analyze and add the above commented code
Since the microtask queue is a first-in, first-out principle, the “out” actually represents the order of the call stack. The new microtasks generated by the chain call are placed at the back of the queue and output later. Therefore, the sibling THEN of each promise code is output successively, and then output downward
****2. What happens when you add microtasks to setTimeout?
When the macro task is executed, the micro task is found and added to the micro task queue. After the macro task is executed and removed from the task queue, there are still microtasks in the microtask queue, and the execution stack is called to execute the microtask and remove the task. Finally, the microtask queue removes the microtask, the macro task queue removes the macro task, and the code execution ends. The setTimeout result is printed first and then the microtask result is printed