Vue.js - event loop mechanism

1. Introduction to event loop mechanism       

        JS is a single-threaded language. Browsers and Node.js define their own Event Loop (event loop mechanism) to solve asynchronous problems. The program is divided into "main thread (execution stack)" and "Event Loop thread". The "main thread" executes synchronous tasks sequentially from top to bottom, and the "Event Loop thread" pushes asynchronous tasks into the macro task queue and micro task queue. implement.

        The event loop mechanism tells us the execution sequence of JavaScript code as a whole. Event Loop is an event loop, which refers to a mechanism of browser or Node that solves the problem of non-blocking when javaScript runs single-threaded, that is, we often use asynchronous principle. The "Event Loop thread" first executes the macro task queue, and then executes the micro task queue. If a new micro task is generated during the execution of the micro task, it will continue to execute the micro task. After the micro task is executed, it will return to the macro task. Next cycle. That is, continue to execute the macro task queue first, and then execute the micro task queue.

Macro task:

script(整体代码)/setTimeout/setInterval/setImmediate/ I/O / UI Rendering

Microtasks:

process.nextTick()/Promise/Async、Await(实际就是Promise)/MutationObserver(html5新特性)

setTimeout and setInterval are all task sources, and the tasks they distribute actually enter the task queue.

priority

setTimeout = setInterval 一个队列setTimeout > setImmediate process.nextTick > Promise

2. Classic event loop interview questions

1. The following piece of code is a classic test question about this type of question in the interview, which includes synchronous and asynchronous tasks, and what is the order of several outputs.

setTimeout(function(){
    console.log('1')
});
new Promise(function(resolve){
    console.log('2');
    resolve();
}).then(function(){
    console.log('3')
});
console.log('4');
// 2,4,3,1

        First, divide the tasks, synchronize tasks: new Promise(), console.log('4'); macro tasks : setTimeout(); micro tasks : Promise().then(); Event Loop pushes the synchronization tasks into the execution stack in turn And execute, when encountering macrotasks or microtasks, push them into the macrotask or microtask queue . Execute the synchronization task first. After the synchronization queue is executed, it will go to the micro queue to fetch the task until the micro queue is empty, and then go to the macro queue to fetch the task and execute it . Therefore, the execution sequence of this program is:

        new Promise()、console.log('4')、Promise().then()、setTimeout()。

 2. Example 2

 The answer output is: async2 end => Promise => async1 end => promise1 => promise2 => setTimeout

3. Example 3

        mounted(){
            this.test();

        },
        methods:{
            test(){
                console.log('script start');

                this.async1();

                setTimeout(function() {
                 console.log('setTimeout')
                }, 0);

                new Promise(resolve => {
                    console.log('Promise')
                    resolve()
                })
                .then(function() {
                console.log('promise1')
                })
                .then(function() {
                console.log('promise2')
                })

                console.log('script end')
            },
            async async1() {
                await this.async2()
                    console.log('async1 end')
            },
            async async2() {
              console.log('async2 end')
            },
        }

In the new version of the chrome browser, it is not printed as above, because chrome is optimized, await becomes faster, and the output is:

// script start => async2 end => Promise => script end => async1 end => promise1 => promise2

Analyze this code:

  • Execute the code and output script start.
  • Executing async1() will call async2(), and then output async2 end. At this time, the context of the async1 function will be retained, and then the async1 function will be jumped out.
  • When setTimeout is encountered, a macro task is generated
  • Execute Promise and output Promise. When then is encountered, the first microtask is generated
  • Continue to execute the code and output script end
  • After the code logic is executed (the current macro task is executed), the microtask queue generated by the current macro task is started , and promise1 is output. When the microtask encounters then, a new microtask is generated
  •  Execute the generated microtask, output promise2, and the current microtask queue is executed. Execution right back to async1
  •  Executing await will actually generate a promise return, namely
  • let promise_ = new Promise((resolve,reject){ resolve(undefined)})
  • Execution is complete, execute the statement after await, and output async1 end
  •  Finally, execute the next macro task, that is, execute setTimeout and output setTimeout

Note that the above analysis is that the slow execution of await in old browsers causes async1 to be executed after the microtask is executed.

Guess you like

Origin blog.csdn.net/qq_36384657/article/details/123243433