Thoughts before writing: There are too many articles about Event Loop on major websites and blogs, but in fact, as long as you have a deeper understanding of a certain article, you will find that it is just like this. There is no need to read too much, because everyone’s understanding level is very poor, writing is that thing; The important thing is, when you really understand, you can delve into some of the small questions, and that’s what you really get.
After all this nonsense, what I really want to say is that this article is also about the Event Loop, which is quite ordinary, but if you pay attention to it, you will understand it. If there is an interview, I also provide my own response template at the end; But if you want to know something deep… Oh, I can’t do it!!
What is the Event Loop?
An Event Loop is an Event Loop, but let’s get rid of how it works and talk about why it exists.
First, we know that JS is single-threaded (see comment 1 for details on why it is single-threaded). Tips: Click the right directory is more convenient), since there is only one thread to execute the event, there will be some problems, such as a scene, if xiao Zhang has some tasks, respectively reading, writing homework, eating takeout, do radio gymnastics; Under normal circumstances, Xiao Zhang is after finishing his homework, order a takeaway, and wait for the takeaway to come over to eat, and then do radio gymnastics. During this process, Zhang will actually have a “dry waiting” period 🤔, that is, the time to do nothing and wait for takeout.
Single thread JS and zhang do things are similar, that zhang is lazy, can wait, but if JS also wait, that for the user, this happened blocking ah, absolutely not!! 🤷♀️ (to be precise, JS is not waiting, it is doing those time-consuming things, analogy here is to go to the store to pick up takeout)
This is where Event Loop comes in. It is a mechanism that allows JS to be single-threaded without blocking. Words is, he through some means, so that JS execution of events more efficient; If you have some time-consuming tasks, put them aside and do the immediate ones first. Wait until the results of the time-consuming tasks become available, and then get those results. To xiaozhang here is, after ordering takeout began to do broadcast gymnastics, finished broadcast gymnastics, and then eat to send over the takeout.
Technically speaking, Event Loop is a mechanism for coordinating events, user interactions, script execution, UI rendering, network requests, etc. The way this works is by monitoring the execution stack and the task queue, and if the execution stack is empty, the task is removed from the task queue and pushed onto the execution stack (more on that later), so it is essentially an asynchronous implementation mechanism. (See note 2 for more information on the mechanisms for asynchronous callbacks. Tips: Click the directory on the right for more convenience)
Here are a few concepts you need to know about Event Loop
Synchronous and asynchronous events
Synchronous events refer to the completion of tasks one by one, the execution of statements one by one from top to bottom, and the execution of the next statement. For example, a simple console.log(XXX), just execute to it, print, and then continue. For Xiao Zhang, it means reading books, doing homework and doing radio gymnastics.
However, asynchronous events are relatively time-consuming compared with synchronous events. They need to perform a series of operations, but we only need to know the result in the end, so we will suspend its execution process for the first time, so as not to let it affect our subsequent work. Is to take the takeout to the delivery man to do, Xiao Zhang continued to do radio gymnastics, and finally to eat takeout.
Execution stack
(I won’t show you the JS memory pattern, just click on the Event Loop article. There are stacks, execution stacks, task queues in JS memory.
The execution stack pushes the current execution context (more popularly known as the current function call) into the execution stack and pops it out when it’s done.
Javascript has a main thread and a call-stack. All tasks are put on the call stack to wait for the main thread to execute.
I am not just, very rough to write a small article implementation context and scope – nuggets (juejin. Cn), interested friends, you can through this article, a simple understanding of the implementation of the stack stack out of the stack process.
Task queue
A task queue is a queue for asynchronous tasks, and there’s nothing special about it. But in JavaScript, there are two kinds of task queues, one is macro task queue and the other is micro task queue. We just need to know which are macro tasks and which are micro tasks, and then put the corresponding types of tasks into the corresponding task queue.
Macro task: SetTimeout, setInterval, setImmediate (IE10), I/O, UI Rendering.
Microtasks: process. nextTick (exclusive to Node), Promise, Object.observe(deprecated), MutationObserver (see here for details)
The process of the event cycle
Finally finally to tell what this cycle is a process, no way, who are we to know before leading knowledge, know the of the above, we’ll realize that sentence above, the role of the event loop is, by monitoring the execution stack and task queue, if the execution stack is empty, just remove the task from the task queue execution of pressure into the execution stack.
The specific process is as follows:
In Event Loop, each Loop is called tick, and the task details of each tick are as follows:
- The call stack selects the MacroTask (usually script code as a whole) that is first queued and executes it if there is one;
- Check whether there are microtasks. If there are microtasks, the system keeps executing them until the MicroTask Queue is cleared.
- The browser updates the render, every time the event loop, the browser may update the render;
- Repeat the above steps.
If you watch it for the first time, you may be very fascinated by 👀, but no matter, please listen to me carefully:
First, execute the global Script code, some of which is synchronous and some of which is asynchronous; The asynchronous statement is put into the corresponding Task queue. When the execution stack is empty after the synchronization Task is executed, check whether the execution stack is empty. If the execution stack is empty, the Task (macro Task) is executed. After all microtasks are executed on a first-in, first-out basis, the microTask queue is set to NULL, and the macro task is executed, and so on.
Step by step:
First: execute global Script code;
Second: after the global Script execution is complete, the execution stack is emptied.
Third: execute stack is empty, fetch a task from the macro task queue;
Fourth: check whether there are microtasks, if there are, execute, until empty
Fifth: rendering;
Then repeat three, four, five… .
So you can think of the global Script code as a macro task; Then each cycle will completely follow the three processes of tick;
Without further ado, above
(Lust for Life: a picture stolen, link below 🐱🐉🐱🐉)
Maybe, maybe, you still have questions;
Is not everyone said is the first micro macro??
Wouldn’t an Event Loop have one or more MacroTask queues, and only one MicroTask Queue? What’s wrong with your picture??
My answer to both questions is “Yes, yes, indeed yes.”
In fact, each MacroTask Queue is guaranteed to execute macroTasks in the order in which callbacks are queued. New microtasks created in macrotasks or microtasks are pushed to the MicroTask Queue and executed. Before executing the next MacroTask, all microtasks will be executed first. In other words, the existing MicroTask Queue will be emptied first. Thus, by the time the second MicroTask Queue is created, the first MicroTask Queue has already been emptied. So the Event Loop actually has only one MicroTask Queue.
Attach my own understanding: not too scientific, so only for reference 😜
As I understand it, you can think of each macro task as a family of synchronized code, microtasks, and even macro tasks. The way to enter the main process is to plug the families in one by one, executing each macro task. As it executes, it executes sequentially, and the synchronized code executes; When it encounters its own microtask, it adds it to its microtask queue, and the macro tasks in it join the family behind it, forming a new family. After the synchronization code execution is complete, the microtask queue is checked and the microtask code is executed. When all is done, do a page rendering. Then the next big family is inserted into the main process and the process is repeated.
My interview template
😒 When the interviewer deadpans: Tell me about the Event Loop.
😊 me: JS is single threaded, but when we write code, there will be synchronous execution of code and asynchronous execution of code. EventLoop is one mechanism for handling asynchronous callbacks. The solution is to use an execution stack and an event queue, which is divided into macro and micro task queues. In simple terms, the code from top to bottom, will push synchronous tasks into the execution stack, encounter asynchronous tasks, according to the type of asynchronous tasks, into different event queues, handed to other threads for processing. If the execution stack is empty, the result is fetched from the event queue, put into the execution stack and executed. Each Loop of the Event Loop is called a tick, which is to take out a macro task, check the microtasks in it, execute all the microtasks, if any, and render once. Take out another macro task and continue with the process.
annotation
No, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no. 🤣 🤣 🤣
Note 1: Why is JS single threaded?
A: Because the essence of JS creation is simple manipulation of the DOM, complete some user interaction. If there are multiple threads, conflicts may occur. For example, two threads perform different operations on the DOM at the same time. Which thread should be used? So in order to maintain consistency, JS must be single-threaded, and it has to be single-threaded.
Note 2: What are the mechanisms for asynchronous callbacks?
A: Callback functions, event listeners, publish subscriber patterns, Promises, Generator functions in ES6, async/await in ES7; Specific content recommended to see several ways to handle asynchronous JS – want to travel – blog park (cnblogs.com)
Reference article:
Once Understand the Event Loop (completely solve such interview problems) – Zhihu (zhihu.com)
1.2.8 Event Loop – Front Internal Parameter (gitbook.io)