Before I understood the event loop, I always encountered some strange problems: for example, the callback interface had the data, but the operation after the callback data did not execute properly; Or, for some reason, you have to add a setTimeout to your code to make it work. Especially in the use of Promise, there are all kinds of problems. Meet the problem to solve, but also to know the cause of the problem, so as to hold the audience!
So without further ado, let’s look at a piece of code
console.log('start');
setTimeout(function(){
console.log('setTImeout1')
},0);
new Promise(function(resolve,reject){
console.log('resolve')
setTimeout(function(){
console.log('setTimeout2')
},200);
resolve()
}).then(function(){
console.log('then')});setTimeout(function(){
console.log('setTimeout3')
},0);
console.log('end');
Copy the code
Start resolve end then setTimeout1 setTimeout3 setTimeout2
Before analyzing the results, LET me introduce a few concepts that don’t necessarily correspond to the standard, but will help you understand the JS event mechanism more easily
- Macro task: includes JS overall code, setTimeout, setInterval, setImmediate, I/O, UI renderder, etc
- Micro-task: includes Promise, Object.observe, Process. NextTick, MutationObserver, etc
- Call stack: After js is loaded, the code is read from top to bottom, synchronous code is executed immediately, and asynchronous code is queued up for events
- Event queue: Some code that is not immediately executed is added to the event queue, which is a first-in, first-out data structure; that is, tasks that are added to the event queue are executed first
As we know, JS is single-threaded, that is, there is only one main thread, and the main thread executes the events in the call stack from top to bottom. The code in the task queue is loaded into the function call stack for execution. After the code in the current macro task queue is executed, the code in the macro task queue distributed to the microtask queue is executed. The code in the next macro task queue is then executed and the cycle continues.
A bit of a misunderstanding here is that the setTimeout function itself is actually executed immediately, and the tasks inside it are then distributed to the queue for delayed execution.
- After the code is loaded, the global context goes into the function call stack, and ‘start’ is executed
- encounter
setTimeout
A new macro task queue is created, and tasks within the function are dispatched to this queue for execution - At this time encountered
Promise
, pay attention to,Promise
The code in the first function in theresolve
orreject
Later,then
The function in the method is dispatched to the microtask queue for execution in the event loop. So it immediately prints ‘resolve’. encountersetTimeout2
After, a new macro task queue is created, and its functions are distributed to this new macro task queue.then
The operations in the method are dispatched to the microtask queue to wait - The code continues and hits ‘setTimeout3’ to create a new macro task queue again
- ‘end’ is executed immediately. There are three macro task queues and one micro task queue
- The actions in the microtask queue are executed, that is, ‘then’ is printed, at which point the first round of the event loop ends.
- The first round of the event loop ends, and the next round of the event loop starts, executing the contents of each macro task queue in turn, and the macro task queue functions here are relatively simple
console
Operation, so no new task queue is redistributed, but because of the secondsetTimeout
A delay of 200 milliseconds is set, so ‘setTimeout2’ is printed last.
At this point, you basically have an idea of the cycle of events. Before, a student asked me a question: Click on the next page of the wheel map, but the page does not respond, the code is like this:
getNextPhoto
goToPage
ajax
getNextPhoto
goToPage
As a front-end rookie, hope to get the criticism of each god correction!