This is the fifth day of my participation in the August More text Challenge. For details, see:August is more challenging
First of all, what is an Event Loop? Event Loop is an operation mechanism of computer system. JavaScript uses this mechanism to solve some of the problems caused by single threading.
1. Why is JavaScript single-threaded?
JavaScript is single threaded, depending on what it’s used for. As a browser scripting language, JavaScript’s primary use is to interact with users and manipulate the DOM. This determines that it has to be single threaded, otherwise it will cause complex synchronization issues. For example: Suppose JavaScript has two threads at the same time, one adding content to a DOM node and the other removing the node, and you have some problems.
2. Task queue
Single threading means that all tasks are queued up for execution, and the next task is executed only after the previous one has finished. If the previous task took too long to execute, the next one will have to wait. If the CPU is busy because of a lot of work, then wait for it, but a lot of times the CPU is idle, and that can be a bit of a problem. All tasks fall into two types: synchronous tasks and asynchronous tasks.
Synchronous tasks are executed on the main thread, forming an execution stack, and the next task will only start when the previous task finishes executing.
Asynchronous tasks do not go into the main thread but into a child thread. It does not affect the main thread’s work. The main thread executes as usual. When the asynchronous task has results, such as AJAX data, the callback function is placed in the task queue.
When all the synchronized tasks on the execution stack of the main thread are finished, the system reads the task queue, which is a first-in, first-out queue, and sends the callback functions from the task queue to the main thread for execution.
3. Macro and micro tasks
Asynchronous tasks are divided into macro tasks and micro tasks
Macro task
Macro tasks include: the entire code block in the script tag, setTimeout, setInterval, etc…
Micro tasks
Microtasks include: promise.then (), $vue.nexttick, etc…
async await
Async await is ES7 syntax. Async is written before a function declaration to indicate that the function is an asynchronous function. “Await” is to be used in combination with async. Writing “await” inside an async function makes the async function immediately following “await” synchronous.
- For await, after the subsequent functions of the await are executed, the following synchronization logic is placed at the end of the execution stack for that round of microtasks.
understand
In my own understanding, when JavaScript is executing, there are three execution stacks. One is synchronous execution stack: all code is executed from top to bottom, and the previous step blocks the next. The second is the microtask execution stack: JavaScript executes from top to bottom. When a microtask is encountered, the callback function will be placed in the microtask execution stack. The third is macro task execution stack. JavaScript is executed from top to bottom. When a macro task is encountered, the callback function will be placed in the macro task execution stack. When the synchronous execution stack code execution is completed, the system will find the microtask execution stack, when the microtask execution stack task execution is completed, then execute the macro task execution stack.
example
- Example 1
console.log('1')
setTimeout(function () {
console.log('2')});new Promise(function (resolve) {
console.log('3');
resolve();
}).then(function () {
console.log('4')
setTimeout(function () {
console.log('5')}); });new Promise(function (resolve) {
console.log('6');
resolve();
}).then(function () {
console.log('7')
setTimeout(function () {
console.log('8')}); });Copy the code
- Example 2
async function aaa() {
function fun1 (num) {
console.log(num)
}
new Promise((res) = > {
fun1(3);
res(4)
}).then((res) = > {
fun1(res);
})
await fun1(1);
fun1(2)
}
aaa();
async function aaa() {
function fun (num) {
console.log(num)
}
new Promise((res) = > {
fun(3);
res(4)
}).then((res) = > {
fun(res);
})
setTimeout(() = > {
fun(5);
},0)
await fun(1);
fun(2)
}
aaa();
Copy the code
- Example 3
async function async1() {
console.log(1)
await async2()
console.log(2)}async function async2() {
console.log(3)}console.log(4)
setTimeout( e= >{
console.log(5)},0)
async1()
new Promise( res= >{
console.log(6)
res()
}).then( e= > {
console.log(7)})console.log(8)
Copy the code