The title

– Please describe the mechanism of event loop (event loop/event polling)

See the Event Loop diagram

– What are macro tasks and micro tasks, and what is the difference between them?

See macro task

– What are the three states of Promise? How does it change?

See Promise for three states

– Connection of promise then and catch

/ / 1
Promise.resolve().then(() = > {
    console.log(1) / / 1
}).catch(() = > {
    console.log(2)
}).then(() = > {
    console.log(3) / / 3
})

/ / the second question
Promise.resolve().then(() = > { // Return the Promise in the Rejected state
    console.log(1) / / 1
    throw new Error('erro1')
}).catch(() = > { // 返回 resolved 状态的 promise
    console.log(2) / / 2
}).then(() = > {
    console.log(3) / / 3
})

/ / the third topic
Promise.resolve().then(() = > { // Return the Promise in the Rejected state
    console.log(1) / / 1
    throw new Error('erro1')
}).catch(() = > { // 返回 resolved 状态的 promise
    console.log(2) / / 2
}).catch(() = > {
    console.log(3)})Copy the code

– async/await syntax

/ / code 1
async function fn() {
  return 100
}
(async function(){
  const a = fn(); //Promise
  const b = await fn() / / 100}) ()/ / code 2
(async function(){
  console.log('start') / / print 'start'
  const a = await 100
  console.log("a",a) / / print 100
  const b = await Promise.resolve(200)
  console.log('b',b) / / print 200
  const c = await Promise.reject(300) // Do not execute the following code
  console.log('c',c) 
  console.log('end')
})() 
Copy the code

– Sequence of proimse and setTimeout

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

– Async /await order problem

async function async1 () {
  console.log('async1 start')
  await async2() // This sentence will execute synchronously, returning a Promise where 'console.log('async2')' will also execute synchronously
  console.log('async1 end') // with await above, below becomes "asynchronous", similar to cakkback function (microtask)
}

async function async2 () {
  console.log('async2')}console.log('script start')

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

async1()

new Promise (function (resolve) { // After a Promise is returned, then is asynchronous code
  console.log('promise1') // The Promise function executes immediately
  resolve()
}).then (function () { // Async, microtask
  console.log('promise2')})console.log('script end')

// After the synchronous code is executed, repeat the existing asynchronous unexecuted, in order
// 1. "await" in async1 -- microtasks
// 2. setTimeout -- macro task
// 3. Then -- microtasks

Copy the code

knowledge

Event loop (Event loop/Event polling)

  • JS is single threaded
  • Asynchrony is implemented based on callbacks
  • DOM times also use callbacks, based on eventLoop
  • The Event loop is how asynchronous callbacks are implemented

How is JS executed

  • From front to back, line by line
  • If a line of execution fails, stop the execution of the following code
  • Finish the synchronous code first, and then perform the asynchronous

The sample

console.log('Hi')

setTimeout(function cb1(){
    console.log('cb1') / / cb callback
},5000)

console.log('Bye')
Copy the code

graphic

Summarize the Event loop process

  • Synchronizes code and executes it line by line on the Call Stack
  • In case of asynchrony, ‘record’ and wait for timing (timing, network request, etc.)
  • When the time is right, move to the Callback Queue
  • If the Call Stack is empty (that is, the synchronized code is finished) the Event Loop starts working
  • Search for the Callback Queue and move it to the CallStack if any
  • And then continue to search (like perpetual motion machines)

Promise

Three states

  • This is a big pity (there is no result pending), which is a pity (has solved the success) and rejected(failed) resolved state === =settled
  • This is a pity or a pity –>rejected –>resolved===settled

Changes and manifestations of state

  • Pending state, which does not trigger then and catch
  • The depressing state will trigger the subsequent then callback functions
  • The Rejected state triggers the subsequent catch callback

Effects of then and catch on state

  • This is a pity. Then this is a pity. If there is a mistake, I will return rejected
  • This is a pity. If there is a mistake, I will return rejected
// Then () this will be a big promise
Promise.resolve().then(() = > {
    return 100
})

// Then () throws an error and returns a promise in the Rejected state
Promise.resolve().then(() = > {
    throw new Error('err')})// Catch () will not throw errors, which will return a fulfilled promise
Promise.reject().catch(() = > {
    console.error('catch some error')})// Catch () throws an error, which returns a promise in the Rejected state
Promise.reject().catch(() = > {
    console.error('catch some error')
    throw new Error('err')})Copy the code

async/await

Introduction to the

  • Asynchronous callback callback hell
  • Proimse then catch chain calls, but also based on callback functions
  • Async /await is synchronous syntax and eliminates callback functions completely

grammar

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

async function loadImg1() {
    const src1 = 'http://www.imooc.com/static/img/index/logo_new.png'
    const img1 = await loadImg(src1)
    return img1
}

async function loadImg2() {
    const src2 = 'https://avatars3.githubusercontent.com/u/9583120'
    const img2 = await loadImg(src2)
    return img2
}

(async function () {
    // Note: await must be placed in async function otherwise an error will be reported
    try {
        // Load the first image
        const img1 = await loadImg1()
        console.log(img1)
        // Load the second image
        const img2 = await loadImg2()
        console.log(img2)
    } catch (ex) {
        console.error(ex)
    }
})()
Copy the code

Async /await and Promise relationship

  • The async function is executed and returns a Promise object
    • Async functions return Promise objects (if no Promise is returned in the function, it will be wrapped automatically)
async function fn2() {
    return new Promise(() = >{})}console.log( fn2() )

async function fn1() {
    return 100
}
console.log( fn1() ) // equivalent to promise.resolve (100)
Copy the code
  • Await is equivalent to then of Promise
    • Await followed by a Promise object: blocks subsequent code and waits for the state to become resolved before getting the result and continuing
    • Await followed by non-promise objects: will return directly
(async function () {
    const p1 = new Promise(() = > {})
    await p1
    console.log('p1') // Will not be executed}) () (async function () {
    const p2 = Promise.resolve(100)
    const res = await p2
    console.log(res) / / 100}) () (async function () {
    const res = await 100
    console.log(res) / / 100}) () (async function () {
    const p3 = Promise.reject('some err')
    const res = await p3
    console.log(res) // Will not be executed}) ()Copy the code
  • try… Catch catches exceptions instead of the catch of Promise
(async function () {
    const p4 = Promise.reject('some err')
    try {
        const res = await p4
        console.log(res)
    } catch (ex) {
        console.error(ex)
    }
})()
Copy the code

conclusion

  • Async encapsulation Promise
  • Await processing Promise success
  • try… The catch processing Promise failed

Asynchronous nature

  • Async /await is the ultimate weapon against asynchronous callbacks
  • JS is still single threaded, asynchronous, and based on Event loop
  • Async /await is just a syntactic sugar, but smells good!
  • Await is synchronous, but it is still an asynchronous call in nature
async function async1 () {
  console.log('async1 start')
  await async2()
  console.log('async1 end') // This is the key step, which is put in callback and executed last
}

async function async2 () {
  console.log('async2')}console.log('script start')
async1()
console.log('script end')
Copy the code

That is, whenever an await is encountered, the following code is equivalent to being placed in a callback.

for… of

  • for… In (and forEach for) is a regular synchronous traversal that executes first, with the result in one piece
  • for… Of is often used for asynchronous traversal, represented by one result before the next
// Time the multiplication
function multi(num) {
    return new Promise((resolve) = > {
        setTimeout(() = > {
            resolve(num * num)
        }, 1000)})}// // uses forEach, which prints all results after 1s, i.e., the three values are computed together
// function test1 () {
// const nums = [1, 2, 3];
// nums.forEach(async x => {
// const res = await multi(x);
// console.log(res);
/ /})
// }
// test1();

/ / used for... "Of" allows calculations to be executed sequentially
async function test2 () {
    const nums = [1.2.3];
    for (let x of nums) {
        / / in the for... Inside the body of the "of" loop, await is evaluated sequentially
        const res = await multi(x)
        console.log(res)
    }
}
test2()
Copy the code

Macro tasks and Micro Tasks

What are macro tasks and what are micro tasks

  • Macro task: setTimeout and setInterval, Ajax, DOM events
  • Microtasks: Promise async/await
  • Microtasks are executed earlier than macro tasks

Event loop and DOM rendering

Review the execution of the Event Loop

  • Call Each time the Stack is cleared (that is, each poll ends), the synchronization task is complete
  • Both are opportunities for the DOM to be re-rendered, and re-rendered if the DOM structure changes
  • Then the next Event Loop is triggered

Here is:

Code examples:

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

The difference between microtasks and macro tasks

  • Macro task: triggered after DOM rendering, such as setTimeout
    • PS: macro tasks are apis of the browser or NodeJS, outside the ES syntax specification, and are not performed by the JS engine, but by the browser or nodeJS kernel.
  • Microtasks: Trigger before DOM rendering, as Promise
    • PS: Microtasks are the specification of ES syntax and are performed by JS engines such as V8

Here is:

In PS:Firefox: DOM is executed before the microtask is executed. Namely, DOM-> microtasks -> macro tasks