js time loop mechanism

1. JavaScript is single-threaded

JavaScript is a single-threaded programming language with only one call stack, which determines that it can only do one thing at the same time. When the code is executed, the execution context of different functions is pushed into the execution stack to ensure the orderly execution of the code. When executing synchronous code, if an asynchronous event is encountered, the js engine will not wait for the return result, but will suspend the event and continue to execute other tasks in the execution stack. Therefore, JS is a non-blocking, asynchronous, and concurrent programming language.

2. Synchronous and asynchronous

The relationship between synchronization and asynchronousness is similar to when we queue up to eat in a restaurant. Everyone has to queue up one by one to buy food, and this process is very boring. At this time, we can play with our mobile phones while queuing up. It didn't take long for us to wait in line to buy food. This queuing process is a synchronous operation in JS, and playing on a mobile phone is like an asynchronous operation. The difference between synchronous and asynchronous lies in the order of execution of the two tasks of queuing up to buy food and playing with mobile phones.
Synchronize:

JS is a single-threaded language because it runs in the browser's main rendering thread, and there is only one main rendering thread.
The main rendering thread is responsible for a lot of work, including rendering pages and executing JS.
If you use synchronization, it is very likely to cause the main thread to block, resulting in many other tasks in the message queue being unable to be executed. In this way, on the one hand, it will cause the busy main thread to waste time, on the other hand, it will cause the page to be unable to be updated in time, causing the user to get stuck.
So the browser uses an asynchronous method to avoid this. The specific method is that when certain tasks occur, such as timers, networks, and event monitoring, the main thread hands the tasks to other threads for processing, and immediately ends the execution of the tasks and switches to executing subsequent code. When other threads complete, the callback function passed in advance is packaged into a task and added to the end of the message queue to wait for the main thread to schedule execution.
In this asynchronous mode, the browser never blocks, thus ensuring the smooth operation of a single thread to the greatest extent.

asynchronous:

It means that if an asynchronous task can be executed without entering the main thread, the task will enter the main thread for execution. After executing the function or method, you do not need to wait blockingly for the return value or message. You only need to delegate an asynchronous process to the system. Then when the system receives the return value or message, the system will automatically trigger the delegated asynchronous process, thus completing a complete process.

3. Event loop mechanism

The event loop, also called the message loop, is the way the browser renders the main thread.
In Chrome's source code, it starts a for loop that will not end. Each loop takes out the first task from the message queue for execution, and other threads only need to add the task to the end of the queue at the appropriate time.
In the past, message queues were simply divided into macro queues and micro queues. This statement is no longer able to meet the complex browser environment, and is replaced by a more flexible and changeable processing method.
According to the official W3C explanation, each task has a different type. Tasks of the same type must be in the same queue, and different tasks can belong to different queues. Different task queues have different priorities. In an event loop, the browser decides which queue's task to take. But the browser must have a microqueue. The tasks in the microqueue must have the highest priority and must be scheduled and executed first.

async function async1() {
    
    
    console.log("async1 start")  //顺序2
    await async2()
    console.log("async1 end") //顺序6
}

async function async2() {
    
    
    console.log("async2")  //顺序3
}

console.log("script start") //顺序1

setTimeout(function () {
    
    
    console.log("setTimeout")  //顺序8
}, 0)

async1()

new Promise(function (resolve) {
    
    
    console.log("promise1")//顺序4
    resolve(123)
}).then(function () {
    
    
    console.log("promise2")  //顺序7
})

console.log("script end") //顺序5

Why is the execution order like this? Shouldn't it be async2executed after the execution is completed async1 end? , I will give you the answers one by one next.
First of all, js is a single-threaded language, and synchronization tasks are executed first, so they will be executed first script start, and then setTimeouta macro task. However, in the event execution sequence of js, the code execution priority in the macro task queue will be lower than that of the synchronization task, so setTimeout It will be added to the macro task queue and wait for the completion of the synchronization task. Then, the code will execute async1the function, so the execution order is 2 async1 start.
Then, here comes the highlight. Async/await is syntactic sugar for Promise, so the code in async1 above can be written like this

async function async1() {
    
    
    console.log("async1 start")
    new Promise(async2()).then(()=>{
    
    
    	console.log("async1 end")
    })
}

According to the characteristics of Promise, Promise is executed synchronously internally, but it .thenis asynchronous, so after execution, async2js will execute the next synchronous code, and it will naturally execute the subsequent synchronous code.
After the synchronization code is executed .then, the promise callback finally executes setTimeout in the macro task list.

Guess you like

Origin blog.csdn.net/qq_44734358/article/details/131283433