– Event Loop

The process of Event Loop

Event Loop is a mechanism for IMPLEMENTING asynchronous task execution in JS.

JS is a single-threaded scripting language. There is only one thread, which we call the main thread.

The code runs on the main thread, producing heap and stack. The heap holds the reference data types, and the stack holds the basic data types and the running space of the function when it executes.

Tasks are classified into synchronous and asynchronous tasks. Macro tasks and micro tasks belong to asynchronous tasks. A synchronous task is executed from top to bottom. If something gets stuck in the middle, it will block and the code behind it will not load. Just like when going to school, a class of people, all want a pace, the front of the people behind fast follow fast, the front of the people slow down, behind the people can not go more than, can only [block] in the back. An asynchronous task is executed independently and can return a result or no result when it is finished. Just like the playground at night, some people take a walk, some people run, the pace of the two people must be different, also need not be the same, you walk your I run mine, you walk whether I run or not has nothing to do with.

JS is a single-threaded language, that is, only one task can be executed at a time, that is to say, the code execution is synchronous and blocked. The disadvantages of synchronous execution need not be mentioned, so the need for asynchronous tasks cannot be avoided.

The browser reads the code, synchronizes the code directly into the call stack, and then executes on the main thread. Asynchronous tasks are queued — asynchronous code is not put on the call stack.

The main thread performs tasks in the Call stack. The call stack is most often used to hold the return address of a subroutine. So, for example, my understanding is that a function is a reference data type, it puts something in the heap, it puts a reference address in the stack, it calls the stack and it holds the reference address, and when it gets to the function, it reads the reference address, and then it executes the heap.

A task queue is all calls to (asynchronous) tasks on the main thread. More generally, synchronous tasks are placed on the call stack and are called directly by the main thread in order. The asynchronous task is put into the task queue first, and when the call stack is empty (the synchronization task of this round is completed), the main thread will execute the task in the task queue. An event loop has one or more task queues. A task queue is A set of tasks. An event loop has one or more task queues.

It says that macro/micro tasks fall under the category of asynchronous tasks. The origin of the word “Macrotask” is unknown, but it is officially called a task. . Macrotask, such as: Script (whole code), I/O, setTimeout, setInterval and other microtasks, each event loop has a Microtask queue, which is a Microtask queue, initially empty. For example, a set of event loops, such as Promise, in which a synchronous task is executed and then an asynchronous task is executed, will clear the microtasks created in that macro task before moving on to the next macro task

I'm not going to say what counts as a macro task or a micro task, because that's not the point, and this article is just to clarify the mechanics, not the specifics.Copy the code

Asynchronous tasks are divided into macro tasks and micro tasks. The asynchronous tasks enter the task queue, and the task queue is naturally divided into macro task queue and micro task queue.

Example 🌰

At this point, we are ready to look at examples:


    console.log(1)
    
    setTimeout(function() {
        console.log(2)},0)
    
    // Note: New PROMISE task synchronization, then() task asynchronous - microtask
    new Promise(resolve= >{
        console.log(3)
        resolve()
    }).then(() = >{
        console.log(4)})console.log(5)
    
Copy the code

Outputs: 1,3,5,4,2

  1. console.log(1)Put it on the call stack, the main thread executes,Output 1
  2. setTimeout(...)Is a macro task, put into the macro task queue
  3. new Promise(resolve=>{ console.log(2); resolve() }).Put it on the call stack, the main thread executes,The output of 2
  4. then(...)It’s a microtask. Put it in the microtask queue
  5. console.log(5)Put it on the call stack, the main thread executes,The output of 5
  6. At this point, the synchronization task is completed, the call stack is empty, and the task queue is polled to execute the tasks in the microtask queue.
  7. then(…) In theconsole.log(3)Put it on the call stack, the main thread executes,The output of 3
  8. At this point, the microtask queue is emptied, the call stack is empty, the task queue is polled, and the tasks in the macro task queue are executed.
  9. setTimeout(…) In theconsole.log(2)Put it on the call stack, the main thread executes,The output of 2

So far, this is a set of processes for the event loop. Of course, there are some things that are not perfect, such as call stacks and task queues. See you there’s another step, so let’s continue.

supplement

In “Event Loop”, I almost didn’t ask “why”, but just said “what”, and I didn’t make speculation by referring to various sources. This is because I am afraid with my writing ability, write too much, but write without focus, messy. So in this “supplement”, let’s talk about something that wasn’t mentioned above.

Let’s start with a picture:

Speaking of the cycle of events, there is always the figure above, as I wrote above, does not seem to fit this diagram, am I wrong?

Start with the callback Queue in the figure

I think the callback queue is a different way of saying that the task queue is the same thing. It’s also called an event queue or message queue. Basically the queue that the main thread polls when the call stack is empty.

Polling is an action. The main thread performs tasks in the call stack, and when the call stack is empty, it performs tasks in the task queue. When the call stack is empty, the JS runtime environment keeps checking to see if there are any tasks in the task queue, and this repeated checking action is called polling.

To see what the queue should be called, quote from this article:

A task queue is neither a queue of events nor a queue of messages.

A task queue is everything you call on the main thread.

Event-driven is the abstraction of everything into events. IO completion is an event, a mouse click is an event, Ajax completion is an event, an image load is an event

A task does not necessarily generate events, such as fetching the current time.

When an event is generated, it is placed in a queue, waiting to be processed

As you can see, the names of event queues and message queues don’t seem to hold water.

And the callback queue, they say this:

Callbacks are code that is suspended by the main thread. Asynchronous tasks must specify a callback function, which is executed when the asynchronous task returns to the execution stack from the “task queue”.

Now look at what the author said in the article:

They were never executed, so why hang them?

Asynchronous tasks do not necessarily need callback functions.

There is never an execution stack. The main thread is always executing. The main thread constantly checks the event queue

Note: He seems to refute the idea of "callback queue" as well as the idea of "execution stack", but I think that the execution stack (call stack) can exist, where code is parsed into variables and instructions are stored in memory, and the CPU reads and executes from top to bottom, thinking that the instructions stored in memory are the execution stack.Copy the code

In summary, I think the task queue argument is more reliable. It’s also used in HTML Standard. To say otherwise would only confuse and make learning more difficult.

Let’s talk about the Web APIs in the diagram

In the Event Loop, it is said that asynchronous code is not put into the call stack, and asynchronous tasks are put into the task queue. What is not mentioned is that there is one more step before an asynchronous task enters the task queue.

Some people say it goes through the Event Table, some say it goes through the Web APIs.

The first said the Event Table

About the concept of Event Table, someone said

An Event Queue is simply a Queue of Callback functions, so it is also called a Callback Queue. When an Event in the Event Table is triggered, the corresponding Callback function of the Event is pushed into the Event Queue and waits to be executed

Others say

The Event Table is a registry: the call stack tells the Event Table to register a function that will be called five seconds later. When the specified Event occurs, the Event Table moves this function to the Event Queue

SetTimeout (firstFunction, 5000);Copy the code

The asynchronous code is registered in the “Event Table” first. If the timer is 5000ms, the task in the callback function in the timer is put into the task queue 5 seconds later. If it is a Click event, wait until the click event is triggered to put the task in the callback function into the task queue.

Take a look at the last few lines of this article

To be precise, in an event-driven system, there must be an awful lot of events. If all events are generated and processed by the main loop, the main thread is bound to be busy. For application-level code, there must be a lot of events that you don’t care about (click events, timer events). This leads to certain waste.

One important concept not covered in this article is Watcher. The observer.

In fact, not all events are placed in a queue.

Different events, placed in different queues.

When we’re not using timers, we don’t care about the timer event queue at all

When we make a timer call, we first set up a timer watcher. During the event loop, the Watcher is called to check whether an event has occurred on its event queue.

When we perform disk I/O, we first set up an IO Watcher. After disk I/O is complete, an event will be added to the EVENT queue of the IO Watcher. The event loop processes events from the Watcher. After processing the existing events, process the next Watcher

Once you’ve checked all the Watchers, move on to the next round

When you don’t care about a certain kind of event, there is no related Watcher

Besides, Web APIs

Web API containers

Web API calls within the call stack are distributed to the Web API container, such as event listeners, HTTP/AJAX requests, or timer functions, where the events remain until the trigger condition is reached. Either a click event is triggered, an HTTP request is completed to retrieve data from a data source, or a timer reaches its trigger point. Once the trigger condition is reached, a callback function is pushed into the fourth and final container: the callback queue.

Talking about web API, I think it is the function, interface that the browser exposes to the outside world. For example, in the following code, add is the exposed function and interface. It can only be read and used externally, but it is not known how to implement it internally, nor can it be changed.

let mywindow = function(){
    let obj = {
        add: function(a, b){
            return a+b
        }
    }
    return obj
}

mywindow().add(1.2) / / 3
Copy the code

summary

Essentially, I think the Event Table and the Web apis are two words for the same thing. That’s a matter of opinion.

twitter

This article has been written intermittently for two or three days, the original intention is to see if I can say what is the event cycle after reading so many articles. It is easy to confuse so many concepts after reading so many articles at the same time, so I hope to write an article to help you.

In the past, when I read articles, I read one letter after another, based on which, when I see different statements, it will be confused, but in fact, they are all the same thing. But am I really right? Not necessarily, but you have to have your own thoughts and it’s all my own thoughts, my own summary, are they really the same thing? Could it be any different?

Is it really not true about task queues, callback queues? What is an asynchronous task? Tasks that will not be executed immediately. Since it will not execute immediately, it must call code when it executes. Can’t this string of code be called a function?

I said some messy things, please criticize me if I have mistakes or omissions.

Reference links:

  • How to explain Event Loop to the satisfaction of the interviewer?
  • Microtasks, macro tasks, and Event-loops
  • JS event loop macro/micro task
  • “Beat the interviewer” thoroughly understands the cycle of events, macro tasks, and micro tasks
  • JavaScript Event Loop
  • A rebuttal to ruan Yifeng’s article: how JavaScript works: Talk about Event Loop again
  • JS runtime environment