Make writing a habit together! This is my first day to participate in the “Gold Digging Day New Plan · April More text challenge”, click to see the details of the activity.
The browser
Browsers are multi-threaded and multi-process. For example, each TAB page in the browser is a separate rendering process under the browsing thread. Js engine threads, HTTP request threads, timed trigger threads, timed trigger threads, GUI threads, these threads provide the technical basis for JS to perform asynchronous tasks in the browser
event-driven
Event triggering, task selection, and task execution are all event-driven. Nodejs and the design of the browser are all based on event-driven event loops, which are a set of processes that manage and execute events in event-driven mode
An Even Loop is a Loop of events
First js is a single thread, the browser is multi-threaded, the execution of JS code thread only one is provided by the browser JS engine thread how to do not block in the execution process, the browser node provides an event loop mechanism to prevent js single thread running Browsers and Nodes do not block when executing a single thread of JS, and the event-event loop mechanism is the principle we often use asynchronously
Event loops in the browser
In JS, tasks are divided into two types, a macro task and a micro task
Macro and micro tasks
1. Macro tasks:
- setTimeout
- setInterval
- SetImmediate (Not supported by browsers, but only by IE10
- RequestAnimationFrame (browser only)
- I/O
- UI Rendering (browser only)
2. Microtasks:
- Promise async awit
- Object.observe
- MutationObserver
Comparison: Features of macro tasks: There are clear asynchronous tasks to be executed and callbacks, and other asynchronous threads need to support microtasks: There are no clear asynchronous tasks to be executed, only callbacks, and no other asynchronous threads need to support microtasks
3. Why are macro tasks and micro tasks distinguished
- The call stack
The call stack is a lifO data structure that is added to the top of the stack when a function is executed, and removed from the top of the stack when the execution stack is complete until the stack is empty
- Task queue
A queue is a first-in, first-out data structure.
Synchronous and asynchronous tasks
Js single-threaded tasks are divided into synchronous and asynchronous tasks
The synchronous task will wait for the main thread to execute the asynchronous task in sequence in the call stack. After the asynchronous task has the result, the registered callback function will be put into the task queue to wait for the main thread to idle (the call stack is cleared), and will be read into the stack to wait for the execution of the main thread
Why?
Asynchronous call stack message queue setTimeOut The evenloop loop is generated when the microtask queue is finished
The micro task executes before the macro task and a DOM render is separated between the macro task and the micro task
Why distinguish between bonus tasks and microtasks task queue fifO if there are priority tasks to introduce microtasks
Event loop in node
Add the callback to the polling queue for final execution
- Loop + task queue flow
- Micro tasks take precedence over macro tasks
Other common forms of asynchrony in NodeJS:
- File I/O read – Load local files asynchronously
- Setimmediate () – Similar to setTimeout setting 0ms, setimmediate() executes immediately after certain synchronization code has completed
- Process.nexttick ()- Executed immediately after certain synchronization tasks have completed
- Server close Closes the callback
The event loop in NodeJS is executed primarily in the Libuv library
Nodejs’ cross-platform and event loop mechanisms are reserved for the Libuv library
Libuv library how to loop:
- Timers stage, which executes all setTimeout () setinterval() callbacks
- A callback for some system operation (such as a TCP connection error)
- Idle Prepare is for internal use only
- Poll training waits for events such as new links and requests, performs I/O callbacks, and so on
- The check SetimMediate callback function executes
- Close callback Turns off callback execution, such as socket.on(‘close’,…)
Actually the process in Node V10 and before:
- Complete all tasks in a phase
- Execute the contents of the nextTick queue
- Complete the microtask team
However, after Node V10, the behavior of the browser is consistent
timers
Execute setTimeout and setInterval callback, both of which require a number of milliseconds to be set. In theory, the callback should be executed as soon as the time is up, but that is because system scheduling may be delayed and not reach the expected time
Examples of official documentation:
const fs = require('fs');
function someAsyncOperation(callback) {
// Assume this takes 95ms to complete
fs.readFile('/path/to/file', callback);
}
const timeoutScheduled = Date.now();
setTimeout(() = > {
const delay = Date.now() - timeoutScheduled;
console.log(`${delay}ms have passed since I was scheduled`);
}, 100);
// do someAsyncOperation which takes 95 ms to complete
someAsyncOperation(() = > {
const startCallback = Date.now();
// do something that will take 10ms...
while (Date.now() - startCallback < 10) {
// do nothing}});Copy the code
When it enters the time loop, it has an empty queue (fs.readfile () has not yet completed), so the timer will wait for the remaining milliseconds. When 95ms u is reached, fs.readfile () completes reading the file and the callback that takes 10 milliseconds to complete is added to the polling queue and executed
When the callback ends, there are no more callbacks in the queue, so the event loop sees that the threshold for the fastest timer has been reached and returns to the Timers stage to execute the timer callback
So in this example, you will see that the total delay between the timer being scheduled and the callback being executed will be 105ms
poll
This poll phase has two main functions
- perform
I/O
The callback - Handling events in the polling queue (callback back to the Timer phase)
When the event loop enters the POLL phase and there is no timer to execute in the timer, one of two things happens:
- If the poll queue is not empty
- The event loop iterates through its callback queue synchronously until the queue is empty, or reaches
system-dependent
(System related restrictions)
2. If the poll queue is empty, the following two situations occur
- If the setImmediate() callback needs to be executed, it immediately stops executing the poll phase and enters the execution Check phase to perform the callback
- If no setImmediate() callbacks need to be executed, the mediate() setup waits for the callback to be added to the queue and executes immediately. There is also a timeout setting that prevents waiting forever
If a timer is set and the poll queue is empty, the poll queue checks whether a timer has timed out and returns to the Timers phase to perform a callback
check
This phase allows people to perform callbacks immediately after the poll phase is complete
The setImmediate() callback is added to the CHENk queue, and the sequence of the check phase follows the poll phase as shown in the following example
console.log('start')
setTimeout(() = > {
console.log('timer1')
Promise.resolve().then(function() {
console.log('promise1')})},0)
setTimeout(() = > {
console.log('timer2')
Promise.resolve().then(function() {
console.log('promise2')})},0)
Promise.resolve().then(function() {
console.log('promise3')})console.log('end')
Copy the code
start=>end=>promise3=>timer1=>timer2=>promise1=>promise2
thinking
- Will every Eventloop be accompanied by a render
requestAninmationFrame
At which stage is it executed, before or after rendering? inmicroTask
Before or afterrequestIdleCallback
In what phase? How to do that? Before or after rendering? inmicroTask
Before or after?resize
,scroll
How are these events distributed
Summary event loop
Event loops are defined to coordinate events, user interactions, scripting, rendering, and networking tasks
- Retrieves a macro task from the macro task queue and executes it
- Check the microtask queue, execute and clear the microtask queue. If a new microtask is added to the microtask queue, it is also executed in this step
- Enter the update rendering stage and judge whether rendering is required. Here is rendering opportunity Eventloop does not necessarily have a browser render for each turn of eventloop, depending on the screen refresh rate, page performance, and whether the page is running in the background. In general, the render interval is fixed (so multiple tasks are likely to execute between renders).
- The browser will try to keep the frame rate as stable as possible, for example if the page performance cannot be maintained at 60fps(render every 16.66ms), the browser will choose 30fps update rate instead of losing frames occasionally
- If the browser context is not visible, the page drops to around 4fps or less
- Rendering is also skipped if the following conditions are met
- The browser determines that updating the render will not result in a visual change
- Frame animation callback is empty and can pass
requestAninmationFrame
To request a frame animation
- If the above judgment determines that rendering is not needed, then the next ones do not continue
- For documents that need to be rendered, if the window size changes, listen
resize
methods - For documents that need to be rendered, execute if the page scrolls
scroll
methods - For documents that need to be rendered, the frame animation callback is performed, i.e
requestAninmationFrame
The callback - For documents that need to be rendered monthly, IntersectionObserver will be executed (if it detects that the visible part of the target element passes one or more thresholds, the specified callback function will be executed).
- For documents that need to be rendered, rerender the user interface
- Determine if both the Task queue and microTask queue are empty, and if so, proceed
Idle
An idle cycle algorithm that determines whether to executerequestIdleCallback
The callback function of
For resize and Scroll, it’s not at this point to perform scrolling and scaling