In js event loop, we need to distinguish the environment, because javascript can run in node environment and browser environment. So we summarize js event cycle from these two aspects.
1, js thread in browser
Is the browser a process? Is there only one thread in it?
At present, most browsers are actually multi process. When we open a tab page, we will start a new process, which is to prevent one page from getting stuck and making all pages unable to respond. There are many threads in each process, including threads executing JavaScript code.
Javascript code is executed in a single thread, which means that JavaScript code can only do one thing at a time. If this thing is time-consuming, it means that the current thread will be blocked.
Therefore, the real time-consuming operations are not actually executed by JavaScript threads. Each process of the browser is multi-threaded, so other threads can complete the time-consuming operations, such as network requests and timers. We only need to execute the callback at a specific time.
2, Browser event loop
The execution process of the above code is as follows:
Because when executing js code, a new JavaScript thread will be created. If asynchronous operations such as timer are encountered, the task will be handed over to other threads of the browser for execution. When the execution is completed, its callback function will be put into the task queue. js will extract the task from the task queue to execute after executing the task in the main thread.
3, Micro and macro tasks in browsers
1. Macro tasks include:
setTimeOut,setInternal,DOM listening, UI rendering, ajax, etc.
2. Micro tasks include:
Promise.then callback, Mutation Observer ApI, queueMicrotask, etc.
3. Execution process
1. First, execute the code in the main program
2. Then, before executing the code of the macro task queue, check whether the micro task queue is empty. If not, take out the tasks in the micro task queue for execution.
3. Before executing macro tasks, ensure that the tasks in the micro task queue are empty.
4, Event loop interview questions in browser
setTimeout(function () { console.log("setTimeOut1") //six new Promise(function (resolve) { resolve() }).then(function () { new Promise(function (resolve) { resolve() }).then(function () { console.log("then4") //eight }) console.log("then2") //seven }) }) new Promise(function (resolve) { console.log("promise1") //one resolve() }).then(function () { console.log("then1") //three }) setTimeout(function () { console.log("setTimeOut2") //nine }) console.log(2) //two queueMicrotask(() => { console.log("queueMicrotask1") //four }) new Promise(function (resolve) { resolve() }).then(function () { console.log("then3") //five }) /* promise1 2 then1 queueMicrotask1 then3 setTimeOut1 then2 then4 setTimeOut2 */
async function async1() { console.log("async1 start") //two await async2() console.log("async1 end") //six } async function async2() { console.log("async2") //three } console.log("script start") //one setTimeout(function () { console.log("setTimeOut") //eight }, 0) async1() new Promise(function (resolve) { console.log("promise1") //four resolve() }).then(function () { console.log("promise2") //seven }) console.log("script end") //five /* script start async1 start async2 promise1 script end async1 end promise2 setTimeOut */
5, node event loop
As shown in the above figure, in the node environment, an event queue and event loop are maintained through libuv, and there is also a thread pool. The tasks in the thread pool are polled continuously and put into the event queue, and finally the tasks in the thread pool are executed.
6, Diagram of node event loop
7, Micro and macro tasks in node
1. Micro task:
next tick queue: process.nexttick
Other queue: then callback function of promise, queueMicrotask
2. Macro task
timer queue: setTimeOut, setInternal
poll queue: I / O event
check queue: setImmediate
close queue: close event
3. Order of execution in node
1,next tick microtask queue 2,other microtask queue 3,timer queue 4,poll queue 5,check queue 6,close queue
8, node event cycle interview questions
async function async1() { console.log("async1 start") // 2 await async2() console.log("async1 end") // 9 } async function async2() { console.log("async2") // 3 } console.log("script start") // 1 setTimeout(function () { console.log("setTimeOut0") // 11 }, 0) setTimeout(function () { console.log("setTimeOut2") // 13 }, 300) setImmediate(() => { console.log("setImmediate") // 12 }) process.nextTick(() => console.log("nextTick1")) // 7 async1() process.nextTick(() => console.log("nextTick2")) // 8 new Promise(function (resolve) { console.log("promise1") // 4 resolve() console.log("promise2") // 5 }).then(function () { console.log("promise3") // 10 }) console.log("script end") // 6 /* script start async1 start async2 promise1 promise2 script end nextTick1 nextTick2 async1 end promise3 setTimeOut0 setImmediate setTimeOut2 */