Front-end interviews often have such a problem plaguing you, which output first, which output after…

Promise.resolve('123').then(data=>{
    console.log(1);
})
process.nextTick(function() {
    console.log(2)
})
setImmediate(function(){
    console.log(3)
})
setTimeout(function(){
    console.log(4)
})
setTimeout(()=>{
    console.log('setTime1');
    Promise.resolve('123').then(data=>{
        console.log('p'); })})setImmediate(()=>{
    console.log('setImmediate1')
    setTimeout(()=>{
        console.log('setTimeout1')})})setTimeout(()=>{
    console.log('setTimeout2')
    process.nextTick(()=>{console.log('nextick')})
    setImmediate(()=>{
    console.log('setImmediate2')})})Copy the code
  • To be honest, WHEN I didn’t know the event loop, I was forced to, what the hell is this…
  • Finish this one and solve all your problems.

1. Js single thread

  • When we talk about event loops, we have to talk about processes and threads. Processes areThe basic unit of the operating system for allocating resources and scheduling tasks, the thread isA unit of program execution built on a processA process can have multiple threads. Open task manager, we will find that each starting task is a process, will occupy memory, CPU, so each web page is a separate process, even if it dies, it will not affect the process of other pages.

1.1 single thread

  • The main thread of JS is a single thread. For example, you cannot operate on a DOM at the same time.

1.2js Other threads

  • In fact, JS also has other threads, such as child threads, such as asynchronous threads (setTimeout, browser events, Ajax callback functions), but what is synchronous and asynchronous?

1.3 Synchronous and Asynchronous

  • Synchronization is when you make a call, it doesn’t return until you get the result, and once it returns, you get the value back. The caller actively waits for the result of the call.
  • Asynchronous is when the caller makes the call and the call returns directly, so no result is returned. The result is not immediately available, but after the call is made, the caller processes the call through status, notification, or callback functions.
  • The asynchrony in JS basically includes timer, Ajax, promise, callback, etc., and we divide these asynchrony into macro task and micro task.

1.4 Macro and micro tasks

  • When it comes to macro and micro tasks, we can divide them into browser and Node.

1.4.1 In browser Environment

  • Macro-task: SetTimeout, setInterval, setImmediate(Ie specific), MessageChannel
  • Micro-task: Promise. Then, the Object. Observe (obsolete), MutationObserver

1.4.2 Node Environment

  • Macro-task: setTimeout, setInterval, setImmediate, I/O
  • Micro-task: Process. NextTick, Promise. Then, the Object, observe (obsolete), MutationObserver(Used in VUE but abandoned due to incompatibility)

1.5 Queues and stacks

  • Queue QueueFifo, like a pipe, goes in one end and comes out the other, as shown here:
  • Stack StackFifin fifout, or last in, first out, as shown in the picture:

    The scenario is that we are the function scope, and the order in which functions are put on the stack isone -> rwo -> threeBut the order of execution isthree -> two -> one

function one() {
    return function two() {return function three() {... }}}Copy the code
  • So what does a queue have to do with a stack? In order to explain the js execution process, synchronous execution of the code is to be placed in the stack execution, and asynchronous code is to be placed in the queue after waiting, get the stack execution, what does it mean?A word of disagreement is above
  • Js is executed in the stack (also known as the main thread), and there is a task queue outside the main thread;
  • Whenever an asynchronous task has a result, an event is placed in the task queue. Once all synchronization tasks in the execution stack are completed, the system reads the task queue and puts the events in the queue into the execution stack one by one for execution.
  • If the event in the queue has microtasks, it will execute the microtask queue after finishing the stack, and then remove the asynchronous task from the macro task queue. This process is continuous. Execute sequence main thread => MicroTask => MacroTask
  • Let me give you an example

2. Browser mechanism

console.log('start');
Promise.resolve('123').then(data=>{
    console.log('Promise1');
});
setTimeout(()=>{
    console.log('setTimeout1');
    Promise.resolve('123').then(data=>{
        console.log('Promise2'); })});setImmediate(()=>{
    console.log('setImmediate1');
    setTimeout(()=>{
        console.log('setTimeout2');
    });
});
setTimeout(()=>{
    console.log('setTimeout3');
    setImmediate(()=>{
        console.log('setImmediate2');
    });
});
console.log('end');
Copy the code
  1. First it executes the stack, and it says: start, end,
  2. And then it’s going to execute the microtask queue that says: promise1,
  3. After execution, read macro tasks one by one while in ChromesetImmediateThe default no wait time is greater than the default wait time of 4mssetTimeoutPut first in the queue.
  4. The order of the queue should besetImmediate1->setTimeout1->setTimeout3According to the queue first in first out, so this time output first:setImmediate1.setImmediate1In thesetTimeout2This timer will be queued after 4ms,
  5. And then go to the queue and get the next itemsetTimeout1Execute, outputsetTimeout1At this time,setTimeout1This timer contains microtaskspromise.then, can be insetTimeout1Execute immediately after execution, and outputPromise1.
  6. I’m going to fetch it from the queuesetTimeout3Put it on the stack, so far if it’s insidesetImmediate2If you’re in 4setTimeout2It’s already in the queue, so first of allsetTimeout2Will be pulled out and put on the stack to execute, if at this pointsetTimeout2It’s not in the queue yet, so that meanssetImmidiate2Will be taken out first and put on the stack for execution.
Start // execute end// Promise1//promise. Then is a microtasksetImmediate1
setTimeout1
Promise2
setTimeout3
setImmediate2// The last two positions should not be determined depending on the execution speedsetTimeout2
Copy the code

3. Node operation mechanism

  • See 1.4.2 for the macro and micro tasks of Node.
  • How does the same thing work in Node? How is it different from the browser environment? A word of disagreement is above
  • Timers stage: This stage executes setTimeout and setInterval’s callback.
  • Poll phase: Performs I/ OS in the POLL phase to check whether the timer is in time.
  • The Check phase: Perform the Callback set by setImmediate();
  • Close Callbacks phase: A callback such as socket.on(‘ close ‘) is executed in this phase.
  • It’s worth noting
  1. Each task will be put into its own queue, only when all the execution of this queue is completed, it will go to the next queue;
  2. In the process of jumping the queue, microtasks will be executed in the queue. Only after the execution is completed, microtasks will be executed in the queue. The execution sequence of each queue is fixed.
  3. For the same microtaskprocess.nextTickFaster thanpromise.then;
  4. Timer -> MicroTask ->I/O-> MicroTask ->setImmidate-> MicroTask.
  5. And forsetTimeoutwithsetImmediateFor, by thenodeDepending on the speed of operation,nodeIf <4ms is enabled, thensetImmediateTo give priority tosetTimeoutPut it in the queue.
  6. whilepollPhase, not only performs I/O operations, but alsoCheck whether the timer expires, if at this timetimerWhen the time comes, it will be executedtimer queneIt doesn’t go any further down, so it’s a lot of things, and it’s very brain-burning.

Thank you for seeing it to the end