An EventLoop is generated in the bank queue

Everyday, we have experienced such a situation, in going to the bank counter to handle business, intends to deal with the business of one of the major things, there could be several other less important business, etc. To be completed before we completely, they turn to the next line, you can imagine this is actually a eventloop?

preface

The content of this article includes the following:

  • Synchronous mode and asynchronous mode
  • Macro and micro tasks and task queues
  • An EventLoop is generated in the bank queue

If you’re already familiar with EventLoop and interested in this article, you can skip to the end of the list and watch the EventLoop in the bank queue

Synchronous mode and asynchronous mode

Why is JavaScript single threaded

We all know that JavaScript is single-threaded, which is why there are two task modes: synchronous and asynchronous. As for why it is designed to be single-threaded, it can be summarized in one sentence, quoting From Teacher Ruan Yinfeng:

As a browser scripting language, JavaScript’s primary purpose is to interact with users and manipulate the DOM. This means that it has to be single-threaded, which can cause complex synchronization problems.

Why is JavaScript single threaded?

Synchronous mode

Official note:

Single-threaded/synchronous mode means that only one task can be done at a time. If there are multiple tasks, they must be queued, the first task completed, the next task executed, and so on.

You can think of it as having a person (let’s call him B) who needs to do a number of things:

  1. Buy vegetables
  2. Cook a meal
  3. Wash the dishes

There was no one to help him, and everything had to be done only after the last thing had been done;

As shown in figure:

Code level:


console.log('begin')

function bar(){
    console.log('bar task')}function foo(){
    console.log('foo task')
    bar()// Again, execute the bar memory address code console.log('bar task')
}

foo() // Can be interpreted as the code that executes the memory address, namely console.log('foo task') and bar()

console.log('end')
foo()

// Output the result
//begin
//foo task
//bar task
//end
Copy the code

Asynchronous mode

Official note:

“Asynchronous mode” is very important. On the browser side, long operations should be performed asynchronously to prevent the browser from becoming unresponsive. The best example of this is Ajax operations. On the server side, “asynchronous mode” is even the only mode, because the execution environment is single-threaded, and if you allow all HTTP requests to be executed synchronously, the server performance deteriorates dramatically and quickly becomes unresponsive.

This is why JS single thread needs to have asynchronous mode, just think about it, if only synchronous mode, some time-consuming tasks will be executed for too long, the task behind can not be executed, which will give users a very bad experience, or even stuck

You can think of it as having A person (let’s call him A) who needs to do A number of things:

  1. Buy vegetables
  2. Cooking (unfamiliar, don’t know how long)
  3. learning

Do these tasks in synchronous mode. We don’t know how long it will take to cook. It may take an hour, two hours, or even longer. This is obviously not possible, so we need a foreign aid at this time, simply call B:

  1. We buy good food
  2. Leave the cooking to B
  3. Then we can study
  4. B Cook dinner and tell us, then the original plan is done

As shown in figure:

Code level:


console.log('shopping')
setTimeout(bar,0) // setTimeout is an asynchronous API, equivalent to B mentioned above, and bar is a callback function for the task we ask B to cook for us
function bar(){
    console.log('cooking')}console.log('learning')


// Output the result
/ / buy vegetables
/ / learning
/ / cooking
Copy the code

conclusion

  • JavaScript runs in single-threaded/synchronous mode
  • The runtime environment provides apis that work in either synchronous or asynchronous mode
  • So when we talk about patterns, we generally mean the way an API works
    • Console. log is the synchronization API
    • Setimeout is the asynchronous API

For more information, see Ruan Yifeng’s article 4 Ways to Write Asynchronous Javascript

Macro and micro tasks and task queues

Task queue

In the previous section, we had an overview of the difference between synchronous and asynchronous;

Official note:

All tasks can be categorized into two types, synchronous and asynchronous. A synchronization task refers to a task that is queued to be executed on the main thread. The next task can be executed only after the first task is completed. Asynchronous tasks are tasks that do not enter the main thread but enter the task queue. The task queue notifies the main thread that an asynchronous task is ready to execute.

It’s a little convoluted, and we’ll go into it in more detail; For the moment, think of a task queue as a queue of tasks waiting to be executed

Macro and micro tasks

A macro task is a macro task that executes the code on each stack. A microtask is a task that is executed immediately after the execution of the current task. That is, after the current task, before the next task, and before rendering.

MacroTasks Microtasks
Script (can be understood as JS running synchronous code for the first time) Promise.then
setTimeout/setInterval Object.observe
The UI rendering/UI events MutaionObserver
PostMessage, MessageChannel Process. NextTick (Node. Js environment)
SetImmediate, I/O (Node.js) .

EventLoop

In an event cycle, each operation is called tick. The task processing model of each tick is complex, but the key steps are as follows:

  • The execution stack selects the first macro task (usually script) to be queued and executes its synchronized code until the end;
  • Check whether there are microtasks, if there are, it will execute until the microtask queue is empty;
  • If the host is a browser, the page might be rendered;
  • Start the next tick, executing the asynchronous code in the macro task (callbacks such as setTimeout).

Here are a few things to know on the basis of the appeal tick:

  • JS is divided into synchronous tasks and asynchronous tasks
  • Synchronization tasks are executed on the main thread, forming an execution stack
  • Outside of the main thread, the event-triggering thread manages a task queue and places an event in the task queue whenever an asynchronous task has a running result.
  • Once all synchronous tasks in the execution stack are completed (the JS engine is idle at this time), the system reads the task queue, adds runnable asynchronous tasks to the executable stack, and starts execution.

It can be said that the above several parts are for the last one we better understand and serve;

EventLoop:

To tell the truth, it’s really hard to understand, the first time I don’t know what it wants to express;

An Eventloop is generated in the bank queue

After seeing this picture, I think I can get a general feeling. Let’s replace the main task with macro task, the secondary task with micro task, and the tasks inside are replaced with API. Then, the teller’s task handling process is shown in accordance with the flow chart

Combined with the stack call flow diagram:

Correspondence:

Official expression:

  • The execution stack selects the first macro task (usually script) to be queued and executes its synchronized code until the end;
  • Check whether there are microtasks, if there are, it will execute until the microtask queue is empty;
  • If the host is a browser, the page might be rendered;
  • Start the next tick, executing the asynchronous code in the macro task (callbacks such as setTimeout).

Examples of banks:

  • The teller gives everyone in line the main task: to apply for a bank card until it is finished
  • The teller will see if there are any secondary tasks to be handled, and deal with the storage value in sequence -> query the balance until the secondary tasks are cleared
  • Finish this person’s business and turn to the next one

conclusion

  • Each cycle of events is a process in which we connect with the teller
  • Execute macro tasks first, and then check whether there are microtask queues. If there are microtasks in the microtask queues, execute them in sequence. If there are no microtasks, execute the next macro task

The last

If I can give you some inspiration or comprehension, I hope you can give me a thumbs-up. If there is any unclear or wrong place, you can point out and leave a comment below. Thank you