Talk more about async await

Firstly, we will briefly talk about async await. In fact, we can write asynchronous code in a synchronous way. In the previous part, we used a Promise to load an image

writing

function loadImg(src) {
  const p = new Promise((resolve, reject) = > {
    const img = document.createElement('img')
    img.onload = () = > {
      resolve(img)
    }
    img.onerror = () = > {
      const err = new Error('Image load failed')
      reject(err)
    }
    img.src = src
  })
  return p
}

const url = 'https://assets.huabyte.com/blog/image/cover1.jpg'

;
(async function () {
  try {
    const img = await loadImg(url) // await is equivalent to then
    console.log(img);
  } catch (ex) {
    console.log(ex);
  }
})()
Copy the code

With Promise

We can start by looking at this code print:

async function fn2() {
  return new Promise(() = >{})}console.log(fn2());

async function fn1() {
  return 100
}
console.log(fn1());
Copy the code

Perhaps we can conclude from the above examples:

  • performasyncFunctionPromiseObject (actualasync awaitGrammar sugar)
  • Await is equivalent to Promisethen
  • try... catchExceptions can be caught instead of the catch of promises

Nature of asynchrony

Writing async await is synchronous syntax, but is essentially an asynchronous call

async function async1 () {
  console.log('async1 start') / / 2
  await async2()
  console.log('async1 end') // 5 The key step is this, which is equivalent to the callback, which is executed last
}

async function async2 () {
  console.log('async2') / / 3
}

console.log('script start') / / 1
async1()
console.log('script end') / / 4
Copy the code

for… Of the usage of the

For a general loop we use for, for… In, and this kind of traversal is also used for regular synchronous traversal operations, we are talking about here is for… Of is often used for asynchronous traversal.

Copy the code

After we have basically said the use of async await and the nature of async await, let’s look at another example:

console.log(100)
setTimeout(() = > {
    console.log(200)})Promise.resolve().then(() = > {
    console.log(300)})console.log(400)
Copy the code

If you look at the print order, it’s 100, 400, 300, 200, and you get a question: setTimeout and Promise then are both asynchronous, why are they executed in a different order than expected?

Microtasks and macro tasks

At the front-end level, we can say the following:

  • Macro tasks: such assetTimeout ,setInterval ,DOMThe event
  • Microtasks: e.gPromise,async await
  • Microtasks are executed earlier than macro tasks

To explain this, we have to go back to the Event loop mechanism again, because DOM rendering and JS code execution are also a thread. At the end of each call stack, DOM rendering is triggered first (not necessarily rendering, just asking if rendering is needed), and then the event loop is performed. The details can be roughly understood by the following illustration

  • Macro tasks: trigger after DOM rendering
  • Microtasks: triggered before DOM rendering

Specific analysis can use code verification

const $p1 = $('

A paragraph of text

'
) const $p2 = $('

A paragraph of text

'
) const $p3 = $('

A paragraph of text

'
The $()'#container') .append($p1) .append($p2) .append($p3) console.log('length', $('#container').children().length ) alert('This call stack has finished, DOM structure has been updated, but rendering has not yet been triggered') // (alert blocks JS execution and DOM rendering for easy viewing) // At this point, the browser will automatically trigger rendering after the call Stack finishes (all synchronization tasks are completed) without code intervention // In addition, according to the event loop trigger DOM rendering time, setTimeout alert, can see the result of DOM rendering setTimeout(function () { alert('setTimeout is the next Call to the Stack, and you'll see the DOM render. ')})Copy the code

If you think deeply about why there is such a difference in treatment, you can understand it as follows:

  • Microtasks: Within the ES syntax standard, the JS engine handles them uniformly. That is, there is no browser about anything, can be processed once, faster and more timely.
  • Macro tasks: ES syntax does not exist, JS engines do not handle, browsers (or NodeJS) interfere with handling.

Practice interview questions

Determine the following print order:

async function async1() {
  console.log('async start'); / / 2
  await async2()
  console.log('async1 end'); // Then callback microtask 6
}

async function async2() {
  console.log('async2'); / / 3
}
console.log('script start'); / / 1

setTimeout(function () { / / macro task
  console.log('setTimeout'); / / 8
}, 0)

async1()

new Promise(function (resolve) {
  console.log('promise1'); / / 4
  resolve()
}).then(function () { Micro / / task
  console.log('promise2'); / / 7
})

console.log('script end'); / / 5
Copy the code