Front-end interview questions: JavaScript event loop (Event loop), macro tasks and micro tasks


The event loop

We all know that the Js engine is single-threaded, which means that every time a bunch of programs are executed, one must be executed before the other is executed. Then someone may ask: Usually we turn on the setTimeout timer, and we haven't seen any influence on the operation of the following programs! It's because javascript has been a single-threaded, non-blocking scripting language since its inception. And its non-blocking is achieved through asynchronous tasks , it can be seen that setTimeout is an asynchronous task.

Then we can know from the above figure: to achieve asynchronous tasks, we need to use the browser's built-in webAPIs module (browser sub-threading) to perform asynchronous tasks.


setTimeout(()=>{
    
    
	console.log('我是异步')
},2000)
console.log('我是同步')

The execution process of the above code:

  1. When the browser parses the Js code into the setTimeoutfunction, the function 入栈finds that the function is asynchronous code, and divides it into the 放入webAPIsbrowser thread 开始计时.
  2. The browser continues the Js code console.log('我是同步'), finds that it is 同步code, and 直接pops the stack to 执行output "I am synchronous"
  3. After nearly two seconds, the browser divides the thread (webAPIs), puts the finished timer function into the callback queuecallback queue (message queue), the browser starts to traverse the callback queue, puts the timer function into the stack for immediate execution, and the console print "I am async"

This operation completes an event loop.

Note: The browser will poll the callback queue only when there is no program to be executed in the execution stack (if there is a callback function in the callback queue, pull it into the execution stack for execution)

2. Macro tasks/micro tasks

The execution order of asynchronous code is different, and it is not executed one by one from top to bottom. Because asynchronous functions are divided into macro tasks and micro tasks.
The execution order is: synchronous task -> asynchronous micro task -> asynchronous macro task

Macro task:

  1. 新程序或子程序被直接执行
  2. 时间的回调函数
  3. setTimeout和setInterval的回调

Microtasks:
1. Promise.then() .catch() .finally()
2. MutationObserver
3.Object.observe

no rendering

// 宏任务
console.log('1')

// setTimeout 的回调是 宏任务,进入回调队列排队
setTimeout(() => {
    
    

    // 宏任务
    console.log('4')
    
    // setTimeout 的回调是 宏任务2,进入回调队列排队
    setTimeout(() => {
    
    
        console.log('7')
    }, 0)
    
    // Promise 的回调是 微任务,本轮调用末尾直接执行
    Promise.resolve()
        .then(() => {
    
    
            console.log('6')
        })
    console.log('5')
}, 0)

// Promise 的回调是 微任务,本轮调用末尾直接执行
Promise.resolve()
    .then(() => {
    
    
        console.log('3')
    })
    
console.log('2')

The above code execution sequence is 1~7 positive sequence output.

Each macro task can be followed by a micro task queue. If there is an instruction or method in the micro task queue, it will be executed; if not, the next macro task will be executed until all macro tasks are executed. The task is equivalent to the small tail of the macro task.
Therefore, this does not violate the first-in, first-out principle of the callback queue. If a macro task is accompanied by a micro task, then the micro task is executed first, the macro task is placed first, and the next micro task is waited. After all of them are executed, start executing the macro task again!


In fact, the complete sequence of browser execution of Js code should be: synchronous task -> asynchronous micro task -> DOM渲染页面-> asynchronous macro task

That's right, between microtasks and macrotasks, the browser will perform a DOM rendering, as in the following case:

with rendering

//向body添加h1节点,内容为Hello
const $content = $('<h1>Hello</h1>')
$('body').append($content)

console.log(1);

Promise.resolve().then(() => {
    
    
    console.log('2.promise');
    alert('promise then')
})

setTimeout(() => {
    
    
    console.log('3 setTimeout');
    alert('setTimeout')
}, 0);

console.log(4);

Execution process:
step1:
insert image description here
After clicking the alert window to confirm, step2:
insert image description here
This proves the conclusion: synchronous task -> asynchronous micro task -> DOM渲染页面-> asynchronous macro task

Guess you like

Origin blog.csdn.net/weixin_60297362/article/details/123298178