Macro task, micro task, async, await principle of interview

Time:2022-3-1

Macro task, micro task, async, await principle of interview

Macro task and micro task of message queue

  • 1: The JS engine executes tasks in a single thread, that is, a pipeline

  • 2: Priority is given to synchronous tasks, and asynchronous tasks are placed in the message queue

  • 3: There are two types of message queues: macro queue (macro task) and micro queue (dimension task)

  • 4: Micro queues take precedence over macro queues,

  • Note 1: even if there is one micro queue in two macro queues, execute the macro queue first, take out the micro queue of the macro queue for execution, and finally point to the next macro queue of the macro queue

  • Note 2:

    • Macro queue (callback function of DOM, Ajax and timer function)
    • Micro queue (promise callback function and mutation callback function)

Message queue example 1

console.log('1')
      setTimeout(() => {
        console.log('2')
      })
      Promise.resolve().then(() => {
        console.log('3')
      })
      console.log('4')
      //The result is: 1 4 3 2
      //Analysis:
      //Log is the priority execution of synchronization tasks 1 - 4
      //SetTimeout is a macro task and promise is a micro task. If the micro task is executed first, it will be 3 first and 2 last

Message queue example 2

const home = this.$refs.home
      let li = document.createElement('li')
      li. InnerHTML = 'I added Li'
      home.insertBefore(li, home.children[0])
      console.log('1')
      setTimeout(() => {
        console.log('2')
        Alert ('block JS macro execution ')
      })
      Promise.resolve().then(() => {
        console.log('3')
        Alert ('block JS execution of micro ')
      })
      console.log('4')
      //The result of adding a micro node (LI) is to block the rendering of a DOM node (LI) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM) (DOM
      //Micro tasks > DOM rendering > macro tasks
      //Analysis:
      //Log is the priority execution of synchronization tasks 1 - 4
      //SetTimeout is a macro task and promise is a micro task. If the micro task is executed first, then 3 before alret (blocking JS from executing the micro task)
      //DOM renders the Li tag. I added Li and finally executed macro task 2

Message queue 3

console.log('1')

      async function async1() {
        await async2()
        console.log('async1')
      }
      async function async2() {
        console.log('async2')
      }
      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('2')
      //Results
      //// first execute the first round: the synchronization task is converted into a synchronization task after using await syntax; The function in the new promise is the synchronization task (promise)
      //// synchronization task result 1 async2 promise 2 async1 executed in the first round
      //In the first round, execute the synchronization task first
      //Async2() in 1 - > await async2() is a synchronization task. Async2 is printed first,
      //The following code is added to the micro task message queue - > and then executed after await processing; The function in the new promise is the synchronization task (promise)
      //Finally, perform the final synchronization task 2
      //Execution result of synchronization task: 1 async2 promise 2
      //Then execute the micro task: async1 promise1, and then the next one Then () is stored in the next micro task
      //If there are no other micro tasks, continue to execute the micro task promise 2 of the next message queue
      //Finally, execute the macro task setTimeout
      //Final result: 1 async2 promise 2 async1 promise 1 promise 2 setTimeout

Message queue 4

setTimeout(() => {
        console.log('0')
      }, 0)

      new Promise(resolve => {
        console.log('1')
        resolve()
      })
        .then(() => {
          console.log('2')
          new Promise(resolve => {
            console.log('3')
            resolve()
          })
            .then(() => {
              console.log('4')
            })
            .then(() => {
              console.log('5')
            })
        })
        .then(() => {
          console.log('6')
        })

      new Promise(resolve => {
        console.log('7')
        resolve()
      }).then(() => {
        console.log('8')
      })
      //Perform synchronization tasks
      //1 - > 7 micro task message queue [2,8]
      //Perform micro tasks:
      //Among micro tasks, synchronization task 2 - > synchronization task 3 - > next message queue [8, 4]
      //Execute 8 - > next message queue [4] first
      //Because micro task 5 is uncertain, it can only be determined after micro task 4 is executed, so - > next message queue [4,6]
      //After executing micro task 4, the micro task 5 in it is determined and placed in the next round of message queue [6,5]
      //Then perform 6 - 5
      //Last macro task 0 executed
      //Results 1 7 2 3 8 4 6 50

The principle of async and await

  • Async and await are actually syntax sugars that encapsulate the generator

Multiple asynchronous nesting

function queryData() {
        return new Promise(function (resolve) {
          resolve(111)
        })
      }
      queryData()
        .then(res => {
          console. Log ('first asynchronous res', RES)
          return Promise.resolve(222)
        })
        .then(res => {
          console. Log ('second asynchronous res', RES)
        })
        .catch(err => {
          console.log('error', err)
        })
      //If there are multiple asynchronies, you need to use multiple then to handle the possible synchronization relationship between asynchronies

How to use yield in ES6

//Simulate a request
      function request() {
        return new Promise(resolve => {
          setTimeout(() => {
            resolve({
              Data: 'I'm data'
            })
          }, 1000)
        })
      }
      //Get the value of request with yield
      function* genGetData() {
        yield request()
      }
      const g = genGetData()
      const { value } = g.next()
      // console.log('g', g, 'value', value, 'done', done)
      //Print {data: "I'm data"} after an interval of 1s
      value.then(res => {
        console.log('data', res)
      })
      // 输出结果:data {Data: 'I'm data'}

Abbreviations of async and await in ES7

//Using async and await
      async function asyncGetData() {
        const result = await request()
        const result2 = await request()
        console.log('result', result, 'result2', result2)
      }
      asyncGetData()