JS Event Loop 2

Source: Internet
Author: User
Tags setinterval

first, let's explain what the event loop is:

As far as we know, the browser's JS is single-threaded, that is, at the same time, at most only one code snippet is executing, but the browser can handle the asynchronous request very well, then exactly why is it? Let's take a look at a picture (this picture comes from http://www.zcfy.cc/article/node-js-at-scale-understanding-the-node-js-event-loop-risingstack-1652.html)

From what we can see, JS main thread It has an execution stack, all the JS code will run in the execution stack. In the execution of the code, if you encounter some asynchronous code (such as Settimeout,ajax,promise.then and user clicks, etc.), then the browser will put the code into a thread (here we call the behind-the-scenes thread) to wait, do not block the main thread execution, The main thread continues to execute the remaining code in the stack, and when the code in the behind-the-scenes thread (background thread) is ready (for example, settimeout time is up, the AJAX request responds), the thread will put its callback function in the task queue for execution. When the main thread finishes executing all the code in the stack, it checks to see if the task queue has a task to execute, and if there is a task to execute, put the task into the execution stack. If the current task queue is empty, it will wait until the task arrives. Therefore, this is called the event loop.

So, here's the problem. If there are a lot of tasks in the task queue, which task do you want to perform first?

In fact (as shown), JS has two task queues, one called Macrotask Queue (Task queue), and one called Microtask queue

    • The former is mainly to carry out some relatively large-scale work, common settimeout,setinterval, user interaction, UI rendering, etc.
    • The latter is mainly carried out in some relatively small work, common with Promise,process.nexttick (NODEJS)

So what is the difference between the two? or, if both tasks appear at the same time, which one should be chosen?
Actually the event loop does the following things:

    1. Check that the Macrotask queue is empty, and if it is not empty, proceed to the next step, and if it is empty, skip to 3
    2. The task of taking the first team (the longest in the queue) from the Macrotask queue executes in the execution stack (only one), then goes to the next step after execution
    3. Check if the Microtask queue is empty and if not empty, go to the next step, or jump to 1 (start a new event loop)
    4. The task of taking the first (longest in queue) from the Microtask queue is executed in the event queue, and after execution, jump to 3

Where the new Microtask task is executed during the current event cycle during code execution, and the new Macrotask task only waits for the next event loop to execute (an event loop executes only one macrotask)
First, let's take a look at some code

Console.log (1) setTimeout (function) {Settimeout1Console.log (2)},0);Const INTERVALID = setinterval (function) {Setinterval1Console.log (3)},0) SetTimeout (function) {Settimeout2Console.log (10)NewPromise (functionResolve) {Promise1Console.log (Resolve ()}). Then (functionconsole.log (12)}). Then (function (console.log (13) clearinterval (Intervalid)})}, 0); //promise2promise.resolve (). Then ( function (console.log (7)}). Then ( function (console.log (8)}) console.log (9)    

What do you think the result should be?
The results I output in the node environment and the chrome console are as follows:

19782310111213

In the example above
First event loop:

    1. Console.log (1) executed, Output 1
    2. SETTIMEOUT1 Execute, join Macrotask queue
    3. Setinterval1 Execute, join Macrotask queue
    4. Settimeout2 Execute, join Macrotask queue
    5. Promise2 executes, and its two then functions join the Microtask queue
    6. Console.log (9) execution, output 9
    7. Based on the definition of the event loop, the next step is to perform the new Microtask task, performing Console.log (7) and Console.log (8) in the order of entering the queue, outputting 7 and 8
      The Microtask queue is empty, back to the first step and into the next event loop, at which point the Macrotask queue is: Settimeout1,setinterval1,settimeout2

Second event loop:

    1. Take the task (SETTIMEOUT1) from the Macrotask queue and execute it, output 2
      The Microtask queue is empty, back to the first step and into the next event loop, at which point the Macrotask queue is: Setinterval1,settimeout2

Third Event Loop:

    1. Take the task (SETINTERVAL1) from the Macrotask queue and execute it, output 3, and then add the newly generated setinterval1 to the Macrotask queue
      The Microtask queue is empty, back to the first step and into the next event loop, at which point the Macrotask queue is: Settimeout2,setinterval1

Fourth event loop:

    1. Take the task (SETTIMEOUT2) from the Macrotask queue and execute it, output 10, and execute the function within new promise (the function in new promise is a synchronous operation, not an asynchronous operation), output 11, and add its two then functions to the Microtask queue
    2. From the Microtask queue, the task of taking the first team is executed until it is empty. As a result, two new microtask tasks are executed sequentially, output 12 and 13, and Setinterval1 are emptied
      At this point, both the Microtask queue and the Macrotask queue are empty, and the browser keeps checking that the queue is empty, waiting for new tasks to join the queue.

Here, you can think, in the first cycle, why is not macrotask first executed? Because according to the process, should not first check Macrotask queue is empty, and then check the Microtask queue?
Cause: Since the first JS main thread running task is the Macrotask task, and according to the event loop process, an event loop will only perform a macrotask task, so after the execution of the main thread code, it will go from the Microtask queue to take the first task to execute.

Note:

Since the Microtask task is executed, it will enter the next event loop only when the Microtask queue is empty, so if it generates a new Microtask task continuously, it will cause the main thread to execute the microtask task. There is no way to perform the Macrotask task, so that we cannot make UI rendering/io operations/ajax requests, so we should avoid this happening. In the Nodejs Process.nexttick, you can set the maximum number of calls to prevent blocking the main thread.

Citation

Https://www.cnblogs.com/chenjg/p/7000044.html

JS Event Loop 2

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.