There is an interview question, a basic interview question about macro and micro tasks, and the code is as follows
console.log('1'); / / 1
setTimeout(function() { / / 2
console.log('2'); / / 3
new Promise(function(resolve) { / / 4
console.log('3'); / / 5
resolve(); / / 6
}).then(function() { / / 7
console.log('4') / / 8})})new Promise(function(resolve) { / / 9
console.log('5'); / / 10
resolve(); / / 11
}).then(function() { / / 12
console.log('6') / / 13
})
console.log('10') / / 14
Copy the code
The answers are: 1,5,10,6,2,3,4
Since I have seen many articles about macro tasks and micro tasks in the form of text and pictures, THIS time I tried to interpret the whole operation process through animation
The operation process is as follows:
- The code runs from top to bottom, which is a block of code that is entered into the task queue as a macro task, and then executed by the event loop during polling, which is called a global task (because it is executed in the global scope). First line 1 (the “//1” identified in the code) prints 1.
- At line 2, it turns out that this is a setTimeout method, and the JS engine will put the setTimeout callback into the delay queue. Yes, the browser doesn’t just have one queue, there are other queues, one of which is the delay queue, and it has names like setTimeout, setInterval, etc., and the rest of which is the delay queue inside the browser.
- Then go to line 9, promise, which is a microtask. The code inside the incoming promise function will be executed immediately. (If you’re interested, take a look at the Promise specification and implement a promise yourself, see this article.) Go to line 10 and print 5.
- When resolve() is encountered on line 11, the callback passed into the then method is placed in the microtask queue.
Just to insert a little bit of knowledge here, actually every macro task has a queue of microtasks, and a common microtask is the Promise, MutationObserver. After the code in the current macro task completes, the task in the microtask queue continues to execute. 5. Then execute the last line, line 14, and print 10. 6. As we mentioned above, after the current macro task completes, it will check whether there are any microtasks in the microtask queue. Before, there was a microtask, which was line 13. So at this point it prints 6. 7. At this point, the macro task of the global task is finished, and the event loop will fetch the next macro task, which will be deferred from the queue. The event loop checks the tasks in the queue back and forth between the task queue and the delay queue. If setTimeout is found to have expired, it will immediately execute the expired macro task in the delay queue, otherwise it will continue to check whether there is a new task in the task queue. When a task is found in the delay queue, line 3 is executed, printing 2. 8. Then we get a promise, and again, execute the function passed in, line 5, and print 3. 9. When resolve is encountered, the then callback is put into the microtask queue. Remember that every macro task has a queue of microtasks, and setTimeout belongs to the macro task. After the macro task is complete, go to the micro task, execute line 8, print 4. After the microtask completes, the current macro task exits the event loop. If another microtask is generated during execution, it is put into the microtask queue until the microtask is empty, and the next macro task is executed.