JavaScript operating mechanism

Foreword

As a front-end er, get to know the most basic requirements of the operating mechanism pair of js. Because js is single-threaded, so js are executed sequentially.

console.log('1')
console.log('2')
输出:1,2。果然是按顺序执行的。本文结束。

To point the complex.

    setTimeout(function () {
      console.log('1')
    })
    new Promise((resolve) => {
      console.log('2')
      resolve()
    }).then(() => {
      console.log('3')
    })
    console.log('4')
输出:2,4,3,1。这个是为啥子嘞。

Speaking from single-threaded js

jsIs a single-threaded language, designed from the beginning, is running in a browser, to facilitate the processing DOMof the tree. If it is multi-threaded, then delete a thread DOM, a thread modification DOM, such problems arise. HTML5It introduces web workersthe jsability to create multiple threads is to prevent large amounts of data to calculate the blocking UIrendering, but these threads are controlled by the main thread, so jsin essence is single-threaded.

Surface very difficult event loop

jsIt is single-threaded, so can only perform one task, when a task takes a long time, the main thread waits to perform tasks in the next task is a waste of resources.
For example, we have those days when the first boil water, while waiting for water to boil, we can open the instant noodles, condiments put away, such as open water, and a direct bubble like. That eating altogether surface away.
Therefore, jsthe task is divided into two, one is a synchronization task, one is asynchronous tasks. Step as shown below:

Macro and micro-task mission

For finer discrimination task, jsthe task may be divided into asynchronous tasks macro and micro tasks.
jsCode, when executed, perform the first jssynchronization task, and then perform all the tasks micro, macro and then perform all the tasks, this cycle continues until the full implementation of all tasks completed.

  • Common macro setTimeouttasks: ,setInterval
  • Common promise.thenmicro-tasks: .
    Look at this code:
    setTimeout(function () {
      console.log('1')
    })
    new Promise((resolve) => {
      console.log('2')
      resolve()
    }).then(() => {
      console.log('3')
    })
    console.log('4')
    
  • 首先执行setTimeout,进入任务队列,注册成宏任务。
  • Promise,直接执行,输出:2,然后promise.then,进入任务队列,注册成微任务。
  • 然后遇到console.log('4'),直接输出:4。
  • 同步任务执行完,从任务队列中找出要执行的微任务,输出:3。
  • 然后执行宏任务,输出:1。
    下面我们看个更复杂的例子:
    console.log('1');
    setTimeout(function () {
      console.log('2');
      new Promise(function (resolve) {
        console.log('3');
        resolve();
      }).then(function () {
        console.log('4')
      })
    })
    new Promise(function (resolve) {
      console.log('5');
      resolve();
    }).then(function () {
      console.log('6')
    })

    setTimeout(function () {
      console.log('7');
      new Promise(function (resolve) {
        console.log('8');
        resolve();
      }).then(function () {
        console.log('9')
      })
    })
    console.log('10')
  • 首先输出:1,然后注册宏任务setTimeout1。然后输出5,注册微任务promise1,然后注册宏任务setTimeout2,然后输出10。所以第一轮的事件循环,输出了1 5 10,注册了微任务promise1,宏任务setTimeout1、setTimeout2
  • 然后promise1进入主线程,执行微任务promise1,输出:6
  • 随后宏任务setTimeout1进入主线程,执行宏任务setTimeout1,输出:2 3,注册微任务promise2
  • 注意的地方来了,宏任务setTimeout1执行完后,我们发现有微任务promise2在任务队列中,所以微任务promise2进入主线程,执行微任务promise2,输出:4
  • 随后宏任务setTimeout2进入主线程,输出:7 8,注册微任务promise3
  • 最后微任务promise3进入主线程,输出:9

Guess you like

Origin www.cnblogs.com/yangrenmu/p/11073959.html