当前位置:网站首页>Finally, I understand the event loop, synchronous / asynchronous, micro task / macro task, and operation mechanism in JS (with test questions attached)
Finally, I understand the event loop, synchronous / asynchronous, micro task / macro task, and operation mechanism in JS (with test questions attached)
2022-07-02 15:38:00 【Mr. fingertip dancer】
Catalog
js It's a single-threaded language
Synchronization task (synchronous)
Asynchronous task (asynchronous)
js It's a single-threaded language
process , The smallest unit of resource allocation , It has independent stack space and data storage space
Threads , The smallest unit of program execution , A process can include multiple threads
If there are multiple processes , Simultaneous operation DOM, Then the consequences are out of control
for example : For the same button , Different processes give different colors , How to show
Single thread means , All tasks are queued , The previous task is over , Will perform the latter task . If the previous task took a long time , The latter task had to wait
JavaScript The language designers realized , The main thread can be completely ignored IO equipment , Suspended pending tasks , Run the next task first . wait until IO The device returned the result , back , Carry on with the suspended task .
therefore , All tasks can be divided into two kinds , One is synchronous tasks (synchronous), The other is asynchronous tasks (asynchronous).
Synchronization task (synchronous)
Synchronous task refers to , Tasks queued for execution on the main thread , Only the previous task was completed , To perform the next task
Asynchronous task (asynchronous)
Asynchronous task means , Do not enter the main thread , And enter ” Task queue ”(task queue) The task of , Only ” Task queue ” Notification thread , Some asynchronous task is ready to execute , This task is then executed on the main thread .
The event loop (Event Loop)
- Synchronous and asynchronous tasks are executed differently " place ", Enter the main thread synchronously , Enter asynchronously Event Table And register functions .
- When the appointed thing is done ,Event Table Will move this function into Event Queue.
- The task in the main thread is empty after execution , Will go to Event Queue Read the corresponding function , Enter the main thread execution .
- The above process will be repeated , That's what they say Event Loop( The event loop ).
Macro task (macrotask)
The code currently executed in the call stack becomes a macro task. . Include :script In the code 、setTimeout、setInterval、I/O、UI render
Micro task (microtask)
At present ( In this cycle of events ) The macro task is finished , Tasks to be executed before the next macro task starts , It can be understood as a callback event
Include :process.nextTick、MutationObserver、Promise.then
promise
Promise Asynchrony in then and catch in , So it's written in Promise The code in is executed immediately as a synchronization task
new Promise(function(resolve) {
console.log('promise'); // Execute now here
resolve();
}).then(res=>{
console.log('rosolve') // Join the micro task (microtask in ) in
})
Async/await
And in the async/await in , stay await Before appearance , The code is also executed immediately . Many people think await We will wait until the expression is executed before continuing to execute the following code , actually await It's a sign to let the thread go . await The following expression will be executed first , take await The following code is added to the micro task microtask in , And then it will jump out of the whole async Function to execute the following code . because async await Itself is promise+generator The grammar sugar of . therefore await The following code is microtask
async function async1() {
console.log('async1 start'); // Execute now
await async2(); // Execute now await The following expression
console.log('async1 end'); // take await The following code is added to the micro task (microtask in ) in
}
Topic 1
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
console.log('script end');
/*
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
*/
analysis :
1. Event loop from macro task (macrotask) The queue begins , Macro task queue , only one script( The overall code ) Mission , Execute the entire code block
2. encounter 2 A defined async function , Keep going down , encounter console sentence , Direct output 'script start'
3.script The task continues down , encounter async1() function ,async Function in await The previous code was executed immediately , So the output 'async1 start', And then execute async2() function , Output 'async2', take ‘console.log('async1 end')’ Assigned to microtask In line
4.script The mission goes on , encounter Promise,Promise The code in is executed immediately as a synchronization task , So the output 'promise1', And then execute resolve, take 'promise2' Assigned to microtask In line
5.script The mission goes on , Finally, only one sentence is output 'script end', thus , The global task is finished
6. After each macro task , I'll check to see if it exists microtask; If there is , execute microtask Until emptied microtask Queue. So in script After task execution , Start searching, clear the micro task queue
7.microtask In line ,Promise There are two tasks in the queue async1 end and promise2, So output in sequence async1 end 、promise2, be-all microtask After execution , Means that the first round of the loop is over
8. The second loop still starts with the macro task queue . At this point, there is only one macro task setTimeout, Take out the direct output , So far the whole process is over
Topic two
Different from question 1 async2() The function is also written inside Promise,Promise The code in is executed immediately as a synchronization task , All will output 'promise1','promise2' Is assigned to microtask In line , So the output is finished 'script end' after , Will be output successively promise2, async1 end ,promise4,setTimeout
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
//async2 Make the following changes :
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
console.log('promise3');
resolve();
}).then(function() {
console.log('promise4');
});
console.log('script end');
/*
script start
async1 start
promise1
promise3
script end
promise2
async1 end
promise4
setTimeout
*/
Question three
analysis :
When output is promise2 after , Next, we will join setTimeout Queue in order to output , Through the code, we can see that the order of adding is 3 2 1, So I'll press 3,2,1 In order to output .
sync function async1() {
console.log('async1 start');
await async2();
// Change it as follows :
setTimeout(function() {
console.log('setTimeout1')
},0)
}
async function async2() {
// Change it as follows :
setTimeout(function() {
console.log('setTimeout2')
},0)
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout3');
}, 0)
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
console.log('script end');
/*
script start
async1 start
promise1
script end
promise2
setTimeout3
setTimeout2
setTimeout1
*/
Question 4
async function a1 () {
console.log('a1 start')
await a2()
console.log('a1 end')
}
async function a2 () {
console.log('a2')
}
console.log('script start')
setTimeout(() => {
console.log('setTimeout')
}, 0)
Promise.resolve().then(() => {
console.log('promise1')
})
a1()
let promise2 = new Promise((resolve) => {
resolve('promise2.then')
console.log('promise2')
})
promise2.then((res) => {
console.log(res)
Promise.resolve().then(() => {
console.log('promise3')
})
})
console.log('script end')
/*
script start
a1 start
a2
promise2
script end
promise1
a1 end
promise2.then
promise3
setTimeout
*/
analysis :
1. Promise.resolve().then(() => {
console.log("promise1");
});
a1();
'promise1' Is also assigned to microtask Queue , And it is in a1() Before function execution , Allocated first , So in 'script end' After output , Output first 'promise1' Then output in turn
2. let promise2 = new Promise((resolve) => {
resolve("promise2.then");
console.log("promise2");
});
This will output directly "promise2", 'resolve' differ 'await', Will not prevent subsequent execution
ending
If this article helps your little friend , Guys, manually like it
We will continue to update the front-end related articles in the future , Thank you for your support
reference :
边栏推荐
- 高考分数线爬取
- 【LeetCode】19-删除链表的倒数第N个结点
- 微信支付宝账户体系和支付接口业务流程
- Leetcode skimming - remove duplicate letters 316 medium
- Wechat Alipay account system and payment interface business process
- There are 7 seats with great variety, Wuling Jiachen has outstanding product power, large humanized space, and the key price is really fragrant
- JVM architecture, classloader, parental delegation mechanism
- 17_ Redis_ Redis publish subscription
- Common English abbreviations for data analysis (I)
- Evaluation of embedded rz/g2l processor core board and development board of Feiling
猜你喜欢
随机推荐
Beijing rental data analysis
彻底弄懂浏览器强缓存和协商缓存
2303. 计算应缴税款总额
[leetcode] 877 stone game
[leetcode] 1254 - count the number of closed Islands
LeetCode刷题——奇偶链表#328#Medium
【LeetCode】1162-地图分析
2022 college students in Liaoning Province mathematical modeling a, B, C questions (related papers and model program code online disk download)
Map introduction
. Net again! Happy 20th birthday
FPGA - clock-03-clock management module (CMT) of internal structure of 7 Series FPGA
Loss function and positive and negative sample allocation: Yolo series
[leetcode] 977 square of ordered array
【网络安全】网络资产收集
14_Redis_乐观锁
Let your HMI have more advantages. Fet-g2ld-c core board is a good choice
16_ Redis_ Redis persistence
Huffman tree: (1) input each character and its weight (2) construct Huffman tree (3) carry out Huffman coding (4) find hc[i], and get the Huffman coding of each character
SQL transaction
14_ Redis_ Optimistic lock