Detailed explanation of the event loop mechanism of javascript browser
This article brings you a detailed explanation of the event loop mechanism of the JavaScript browser. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
Questions thrown in front:
How can a single thread be asynchronous?
What is the process of the event loop?
What are macrotask and microtask, and what are they? What is the difference
Single-threaded and asynchronous
When it comes to js, you will think of single-threaded and asynchronous, so how does a single-thread achieve asynchronousness? Concept first, we must first understand the relationship between single thread and asynchronous.
JS tasks are divided into two types: synchronous and asynchronous, and their processing methods are also different. Synchronous tasks are directly queued for execution on the main thread, while asynchronous tasks will be placed in the task queue. If there are multiple Tasks (asynchronous tasks) have to be queued and waiting in the task queue. The task queue is like a buffer. The task will be moved to the call stack (call stack) in the next step, and then the main thread executes the task of the call stack.
Single thread means that there is only one thread (main thread) in the js engine that is responsible for parsing and executing js code, that is, it can only do one thing at a time, and we know that for an ajax request, the main thread is waiting for its response. At the same time, it will do other things. The browser first registers the ajax callback function in the event table. After the response comes back, the callback function is added to the task queue and waits for execution. It will not cause thread blocking, so the way js handles ajax requests is is asynchronous.
In short, the process of checking whether the call stack is empty and determining which task to add to the call stack is the event loop, and the core of js's asynchronous implementation is the event loop.
Call stack and task queue
As the name suggests, the call stack is a stack structure. Function calls will form a stack frame, which contains context information such as parameters and local variables of the currently executed function. After the function is executed, its execution context is popped from the stack.
The following picture is the relationship between the call stack and the task queue
Event loop
About the event loop, Introduction to HTML specifications
There must be at least one event loop per user agent, and at most
one event loop per unit of related similar-origin browsing contexts.
An event loop has one or more task queues.
Each task is defined as coming from a specific task source.
Understood from the specification , the browser has at least one event loop, and each event loop has at least one task queue (macrotask). Each external task has its own group, and the browser will set priorities for different task groups.
macrotask & microtask
The specification mentions two concepts, but does not introduce them in detail. After consulting some information, it can be summarized as follows:
macrotask: contains the js code that executes the entire , event callbacks, XHR callbacks, timers (setTimeout/setInterval/setImmediate), IO operations, UI render
microtask: tasks that update application status, including promise callbacks, MutationObserver, process.nextTick, Object.observe
Among them, setImmediate and process.nextTick are the implementation of nodejs, which will be introduced in detail in the nodejs article.
Event processing process
Regarding the understanding of macrotask and microtask, it may be a bit obscure if you look at it this way. Combining the event loop mechanism, the understanding is much clearer. The following picture can be said to be an introduction. Very clear.
To sum up, the steps of an event loop include:
1. Check whether the macrotask queue is empty. If it is not empty, go to 2. If empty, go to 3
2. Execute a task in the macrotask
3. Continue to check whether the microtask queue is empty, if so, go to 4, otherwise go to 5
4. Take out the task in the microtask and execute Complete and return to step 3
5. Execute view update
Execution sequence of mactotask & microtask
After reading so many dry words To introduce the concept, why not look at a piece of code to get a feel for it
console.log('start') setTimeout(function() { console.log('setTimeout') }, 0) Promise.resolve().then(function() { console.log('promise1') }).then(function() { console.log('promise2') }) console.log('end')
What is the log sequence output by the print station? Based on the analysis of the above steps, is it so easy~
#First, the global code (main()) is pushed into the call stack for execution, and start is printed;
Next, setTimeout is pushed into the macrotask queue, promise.then callback is put into the microtask queue, and finally console.log('end') is executed to print out end;
At this point, the code in the call stack has been executed. Looking back at the definition of macrotask, we know that the global code belongs to macrotask. After the macrotask is executed, the next step is to execute the task of the microtask queue. Execute the promise callback and print promise1;
promise回调函数默认返回undefined,promise状态变为fullfill触发接下来的then回调,继续压入microtask队列,event loop会把当前的microtask队列一直执行完,此时执行第二个promise.then回调打印出promise2;
这时microtask队列已经为空,从上面的流程图可以知道,接下来主线程会去做一些UI渲染工作(不一定会做),然后开始下一轮event loop,执行setTimeout的回调,打印出setTimeout;
这个过程会不断重复,也就是所谓的事件循环。
视图渲染的时机
回顾上面的事件循环示意图,update rendering(视图渲染)发生在本轮事件循环的microtask队列被执行完之后,也就是说执行任务的耗时会影响视图渲染的时机。通常浏览器以每秒60帧(60fps)的速率刷新页面,据说这个帧率最适合人眼交互,大概16.7ms渲染一帧,所以如果要让用户觉得顺畅,单个macrotask及它相关的所有microtask最好能在16.7ms内完成。
但也不是每轮事件循环都会执行视图更新,浏览器有自己的优化策略,例如把几次的视图更新累积到一起重绘,重绘之前会通知requestAnimationFrame执行回调函数,也就是说requestAnimationFrame回调的执行时机是在一次或多次事件循环的UI render阶段。
以下代码可以验证
setTimeout(function() {console.log('timer1')}, 0) requestAnimationFrame(function(){ console.log('requestAnimationFrame') }) setTimeout(function() {console.log('timer2')}, 0) new Promise(function executor(resolve) { console.log('promise 1') resolve() console.log('promise 2') }).then(function() { console.log('promise then') }) console.log('end')
可以看到,结果1中requestAnimationFrame()是在一次事件循环后执行,而在结果2,它的执行则是在三次事件循环结束后。
总结
1、事件循环是js实现异步的核心
2、每轮事件循环分为3个步骤:
a) 执行macrotask队列的一个任务
b) 执行完当前microtask队列的所有任务
c) UI render
3、浏览器只保证requestAnimationFrame的回调在重绘之前执行,没有确定的时间,何时重绘由浏览器决定
The above is the detailed content of Detailed explanation of the event loop mechanism of javascript browser. For more information, please follow other related articles on the PHP Chinese website!

The main difference between Python and JavaScript is the type system and application scenarios. 1. Python uses dynamic types, suitable for scientific computing and data analysis. 2. JavaScript adopts weak types and is widely used in front-end and full-stack development. The two have their own advantages in asynchronous programming and performance optimization, and should be decided according to project requirements when choosing.

Whether to choose Python or JavaScript depends on the project type: 1) Choose Python for data science and automation tasks; 2) Choose JavaScript for front-end and full-stack development. Python is favored for its powerful library in data processing and automation, while JavaScript is indispensable for its advantages in web interaction and full-stack development.

Python and JavaScript each have their own advantages, and the choice depends on project needs and personal preferences. 1. Python is easy to learn, with concise syntax, suitable for data science and back-end development, but has a slow execution speed. 2. JavaScript is everywhere in front-end development and has strong asynchronous programming capabilities. Node.js makes it suitable for full-stack development, but the syntax may be complex and error-prone.

JavaScriptisnotbuiltonCorC ;it'saninterpretedlanguagethatrunsonenginesoftenwritteninC .1)JavaScriptwasdesignedasalightweight,interpretedlanguageforwebbrowsers.2)EnginesevolvedfromsimpleinterpreterstoJITcompilers,typicallyinC ,improvingperformance.

JavaScript can be used for front-end and back-end development. The front-end enhances the user experience through DOM operations, and the back-end handles server tasks through Node.js. 1. Front-end example: Change the content of the web page text. 2. Backend example: Create a Node.js server.

Choosing Python or JavaScript should be based on career development, learning curve and ecosystem: 1) Career development: Python is suitable for data science and back-end development, while JavaScript is suitable for front-end and full-stack development. 2) Learning curve: Python syntax is concise and suitable for beginners; JavaScript syntax is flexible. 3) Ecosystem: Python has rich scientific computing libraries, and JavaScript has a powerful front-end framework.

The power of the JavaScript framework lies in simplifying development, improving user experience and application performance. When choosing a framework, consider: 1. Project size and complexity, 2. Team experience, 3. Ecosystem and community support.

Introduction I know you may find it strange, what exactly does JavaScript, C and browser have to do? They seem to be unrelated, but in fact, they play a very important role in modern web development. Today we will discuss the close connection between these three. Through this article, you will learn how JavaScript runs in the browser, the role of C in the browser engine, and how they work together to drive rendering and interaction of web pages. We all know the relationship between JavaScript and browser. JavaScript is the core language of front-end development. It runs directly in the browser, making web pages vivid and interesting. Have you ever wondered why JavaScr


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

MantisBT
Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

SublimeText3 Linux new version
SublimeText3 Linux latest version
