The event loop mechanism in js is very interesting. It can also be seen from many interview questions that examining the simple setTimeout is also to examine this mechanism.
Before, I simply thought that because the function executes very quickly, even if the setTimeout execution time is 0, it will not be output immediately, but will wait for the function to be executed before outputting. This is only half true.
In fact, its operating mechanism is the event loop mechanism in js. In this loop mechanism, it is related to call stack and task queue.
The event loop mechanism, to put it simply, is the pushing and popping of functions into the stack during the execution context. The function is pushed onto the stack before execution and popped out after execution. If you encounter some asynchronous operations such as callback functions, ajax, setTimeout, etc., they will first be handed over to other modules of the browser for execution. After execution, the callback functions will be put into the taskqueue. When all the call stacks are executed, the functions in the task queue will be executed.
Give a simple example:
console.log(1); setTimeout(function(){console.log(2);}, 0);console.log(3);
Let’s take a look at the internal process of execution
1. Execute the first sentence, put it in the call stack, and output 1
2. The first sentence is popped off the stack and the second sentence is executed. Since it is executed asynchronously, it is handed over to other modules.
3. After execution, put the callback function into the taskqueue
4. Execute the next sentence, the same as the first step, put The statement is pushed onto the stack and executed, and 3
5 is output. The statement is popped off the stack, and the call stack is empty at this time. Start executing the task queue task and output 2
So, the output result is
which is consistent with expectations.
How does it work if Promise is added?
We know that the callback function of Promise is not passed in, but is called using then. Therefore, the function defined in Promise should be executed immediately, and then is its callback function and placed in the queue.
An important concept is also mentioned in the referenced article:
macro-taskIncludes: script (overall code), setTimeout, setInterval, setImmediate, I/ O, UI rendering.
micro-taskIncludes: process.nextTick, Promises, Object.observe, MutationObserver
Execution sequence: The function call stack is cleared, leaving only the global execution context, and then all micro-tasks are executed. After all executable micro-tasks have been executed. The loop executes a task queue in the macro-task again, and then executes all micro-tasks after execution, and the loop continues like this.
Look at another example:
(function test() { setTimeout(function() {console.log(4)}, 0); new Promise(function executor(resolve) { console.log(1); for( var i=0 ; i<10000 ; i++ ) { i == 9999 && resolve(); } console.log(2); }).then(function() { console.log(5); }); console.log(3);})()
For the specific process, you can read the article above. The approximate process is as follows:
1. When setTimeout is encountered, it is handed over to other modules for execution. After execution, the callback is placed in the macro-task
2. When Promise is encountered, the function inside is executed immediately and 1 is output.
3. The loop starts, encounters resolve(), and changes the Promise status to fulfill. Continue execution and output 2.
4. When then is encountered, put the callback into the micro-task.
5. Continue execution and output 3.
6. The call stack execution is completed. Start executing the callback function in the micro-task and output 5.
7. After the micro-task is executed, the callback function in the macro-task starts to be executed, and 4 is output.
8. End.
The above is the detailed content of In-depth understanding of JS event loop mechanism. For more information, please follow other related articles on the PHP Chinese website!