This article focuses on the following aspects:

  • event loop
  • Promise the advanced
  • async/await
  • Microtask/macro task
  • Scenario question – Connection of promise then and catch
  • Scenario problem -async/await syntax
  • Scenario question – Order of Promise and setTimeout
  • Scenario questions – plus async/await order questions

Essay question

1 Please describe the mechanism of event loop(event loop/event polling), and draw figure 2. What are macro tasks and micro tasks, and what is the difference between them? 3 What are the three states of Promise? How does it change?Copy the code
  • Please describe the mechanism of event loop(event loop/event polling)
  • What are macro tasks and micro tasks, and what is the difference between them?
  • What are the three states of a Promise? How does it change?
  • Scenario question – Connection of promise then and catch
/ / 1
Promise.resolve().then(() = >{
    console.log(1);
}).catch(() = >{
    console.log(2);
}).then(() = >{
    console.log(3);
})
// Print 1, 3

/ / the second question
Promise.resolve().then(() = >{
    console.log(1);
    throw new Error('error1')
}).catch(() = >{
    console.log(2);
}).then(() = >{
    console.log(3);
})
// Print 1, 2, 3

/ / the third topic
Promise.resolve().then(() = >{
    console.log(1);
    throw new Error('error1')
}).catch(() = >{
    console.log(2);
}).catch(() = >{
    console.log(3);
})
// Print 1, 2
Copy the code
  • Scenario problem -async/await syntax
async function fn(){
    return 100;
}
(async function(){
    const a = fn();/ /?? Return a promise value of 100
    const b = await fn(); / /?? Return value 100 (await equals promise then)}) () (async function(){
    console.log('start');
    const a = await 100;
    console.log('a',a);
    const b = await Promise.resolve(200);
    console.log('b',b);
    const c = await Promise.resolve(300);
    console.log('c',c);
    console.log('end'); }) ()// What is printed out after execution?
// Just print start A :100 b:200
Copy the code
  • Scenario question – Order of Promise and setTimeout
console.log(100) setTimeout(()=>{ console.log(200) }) Promise.resolve().then(()=>{ console.log(300) }) console.log(400) / / 100 400 300 200Copy the code
  • Scenario questions – plus async/await order questions
async function async1(){
    console.log('async1 start'); / / 2
    await async2();
    // await as callback content -- microtasks
    console.log('async1 end') / / 6
}
async function async2(){
    console.log('async2') / / 3
}
console.log('script start') / / 1

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

async1();

//**** When a promise is initialized, the callback passed in is executed immediately
new Promise(function(resolve){
    console.log('promise1') / / 4
    resolve()
}).then(function(){ Micro / / task
    console.log('promise2') / / 7
})

console.log('script end')/ / 5

// The event loop-call stack is cleared.
// Perform microtasks
// (try to trigger DOM rendering)
// Trigger Event loop to execute macro task
Copy the code

Event loop(Event loop/Event polling)

  • JS runs in a single thread

  • Asynchrony is implemented based on callbacks

  • The Event loop is how asynchronous callbacks are implemented

  • Review: How is JS executed?

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

The sample

console.log('Hi')
setTimeout(function cb(){
    console.log('cb1')
},5000)
console.log('Bye')
Copy the code

The event loop process

  • Synchronizes code and executes it line by line on the Call Stack
  • In the case of asynchrony, it “records” and waits for an opportunity (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 the Callback Queue and move it to the Call Stack if any exists
  • And then continue to search (like perpetual motion machines)

DOM events and Event loops

  • JS is single threaded
  • Asynchronous (setTimeout, Ajax, etc.) uses callbacks, based on event loops
  • DOM events also use callbacks, based on event loops
console.log('Hi')
setTimeout(function cb(){
    console.log('cb1')
},5000)
console.log('Bye')
Copy the code
<button id="btn1">submit</button>
<script>
console.log('Hi'The $()'#btn1').click(function(e){
    console.log('button clicked')})console.log('Bye')
</script>
Copy the code

Macrotasks and micro tasks

  • What are macro tasks and what are micro tasks
  • Event loop and DOM rendering
  • The difference between microtasks and macro tasks

Code demo

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

Macro and 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

const $p1 = $('<p>A piece of writing</p>');
const $p2 = $('<p>A piece of writing</p>');
const $p3 = $('<p>A piece of writing</p>'); $('#container') .append($p1) .append($p2) .append($p3) console.log('length',$('#container').children().length) //3 Alert (' This call to stack is over, DOM structure has been updated, but rendering has not yet been triggered ') //(Alert will block JS execution and DOM rendering to check the effect)Copy the code
const $p1 = $('<p>A piece of writing</p>');
const $p2 = $('<p>A piece of writing</p>');
const $p3 = $('<p>A piece of writing</p>'); $(' # container). Append ($(p1), append ($(p2), append ($p3) micro / / task: Resolve (). Then ()=>{console.log('length1', $('#container').children().length)//3 alert('Promise then')//DOM renders? --//NO}) // SetTimeout (()=>{console.log('length2', $('#container').children().length)//3 alert('setTimeout') //DOM rendered? ---YES })Copy the code

Explain from the Event loop why microtasks fire before rendering rather than macro tasks

  • By the browser is the macro task: setTimeout and setInterval, Ajax, DOM events
  • Microtasks are specified by ES6 syntax: Promise async/await

Microtasks and macro tasks – Summary

  • What are the macro tasks? What are microtasks? Why do microtasks trigger earlier
  • Relationships between microtasks, macro tasks, and DOM rendering
  • Microtasks, macro tasks, and DOM rendering, in the event loop process
  • Describe the Event loop mechanism (graphable)
    • Review DOM rendering relationships for yourself

    • The different processing of microtasks and macro tasks in the Event loop process

Promise

  • Three states
  • The manifestation and change of state
  • Effects of then and catch on state
    • Review 7- Asynchronous basics
// Image loading
function loadImg(src){
    return new Promise((resolve,reject) = >{
        const img = document.createElement('img');
        img.onload = () = >{
            resolve(img)
        }
        img.onerror = () = >{
            const err = new Error('Image load failed${src}`)
            reject(err)
        }
        img.src = src
    })
}

const url = 'https://img.xxx';
loadImg(url).then(img= >{
    console.log(img.width);
    return img;
}).then(img= >{
    console.log(img.height)
}).catch(err= >console.error(err))

// Fix callback hell:
const url1 = 'https://img1.xxx';
const url2 = 'https://img2.xxx';

loadImg(url1).then(img1= >{
    console.log(img.width);
    return img1;
}).then(img1= >{
    console.log(img1.height)
    return loadImg(url2);
}).then(img2= >{
    console.log(img2.width)
    return img2;
}).then(img2= >{
    console.log(img2.height)
}).catch(err= >console.error(err))

Copy the code

Three states

  • Resolved resolved resolved rejected

  • Resolved or Pending –> Rejected

  • Irreversible change

  • Performance of state

    • Pending state, which does not trigger then and catch
    • Resolved state, which triggers subsequent THEN callbacks
    • The Rejected state triggers the subsequent catch callback
const p1 = new Promise((resolve,reject) = >{})console.log('p1',p1) //pending

const p2 = new Promise((resolve,reject) = >{
    setTimeout(() = >{
        resolve()
    })
})
console.log('p2',p2)//pending
setTimeout(() = >console.log('p2-setTimeout',p2))//resolved


const p3 = new Promise((resolve,reject) = >{
    setTimeout(() = >{
        resolve()
    })
})
console.log('p3',p3)//pending
setTimeout(() = >console.log('p3-setTimeout',p3))//reject

Copy the code

Then and catch change state

  • Then check resolve and rejected if there is an error
  • If catch returns resolve, and if failed, return Rejected
const p1 = Promise.resolve().then(() = >{
    return 100
})
console.log('p1',p1) // Resolved to trigger subsequent then callback
p1.then(() = >{
    console.log('124')})const p2 = Promise.resolve().then(() = >{
    throw new Error('then error')})console.log('p2',p2) // Rejected triggers subsequent catch callbacks
p2.then(() = >{
    console.log('456')
}).catch(err= >{
    console.log('err100',err)
})
Copy the code

const p3 = Promise.reject('my error').catch(err= > {
    console.error(err)
})
console.log('p3',p3) // Resolved note: Trigger then callback
p3.then(() = >{
    console.log(100)})const p4 = Promise.reject('my error').catch(err= >{
    throw new Error('catch err')})console.log('p4',p4)  // Rejected triggers the catch callback
p4.then(() = >{
    console.log(200)
}).catch(() = >{
    console.log('some err')})Copy the code

The print result is as follows:

async/await

  • Asynchronous callback callback hell
  • Promise then catch chain calls, but also based on callback functions
  • Async /await is synchronous syntax and eliminates callback functions completely
// Image loading
function loadImg(src){
    return new Promise((resolve,reject) = >{
        const img = document.createElement('img');
        img.onload = () = >{
            resolve(img)
        }
        img.onerror = () = >{
            const err = new Error('Image load failed${src}`)
            reject(err)
        }
        img.src = src
    })
}

const url = 'https://img.xxx';
loadImg(url).then(img= >{
    console.log(img.width);
    return img;
}).then(img= >{
    console.log(img.height)
}).catch(err= >console.error(err))

// Fix callback hell:
const url1 = 'https://img1.xxx';
const url2 = 'https://img2.xxx'; Define an anonymous function,awaitWant to useasyncPackage execution (async function(){
    const img1 = await loadImg(url1)
    console.log(img1.width)
    
    const img2 = await loadImg(url2)
    console.log(img2.width)
    
})()

// equivalent to the following function

loadImg(url1).then(img1= >{
    console.log(img.width);
    return img2;
}).then(img2= >{
    console.log(img2.width)
})
Copy the code
Define an anonymous function,awaitWant to useasyncPackage execution (async function(){
    const img1 = await loadImg(url1)
    console.log(img1.width)
    
    const img2 = await loadImg(url2)
    console.log(img2.width)})() (awaitI can call a new oneasync awaitfunctionasync function loadImg1(url1){
    const img1 = await loadImg(url1)
    return img1
}
async function loadImg2(url2){
    const img2 = await loadImg(url2)
    return img2
}
(async function(){
    const img1 = await loadImg1(url1)
    console.log(img1.width)
    
    const img2 = await loadImg2(url2)
    console.log(img2.width)
})()
Copy the code

Async /await and Promise relationship

  • Async /await is the ultimate weapon against asynchronous callbacks, but promises and async are not mutually exclusive, they complement each other
  • The async function is executed and returns a Promise object
  • Await is equivalent to then of Promise
  • try… Catch catches exceptions instead of the catch of Promise
async function fn1(){
    //return 100; //return
    return Promise.resolve(100)}const res1 = fn1() // Perform async and return a Promise object
console.log('res1',res1)  / / Promise object
res1.then(data= >{
    console.log('data',data) / / 100
})
Copy the code

Await equals promise.then

! (async function(){//! Just isolate the preceding statement to avoid the previous statement without '; Resolve (300) const data = await p1 // = promise.then console.log('data',data)})()! Resolve (222) console.log('data1',data1)})() async function fn1(){ //return 100; Return Promise. Resolve (100)}! (async function(){ const data2 = await fn1() console.log('data2',data2) })()Copy the code

Using a try… catch

! (async function(){
    const p4 = Promise.reject('err1') 
    try{
        console.log('intry 1')
        const res = await p4
        console.log(res)
    }catch(err){
        console.log('p4err',err)// try... Catch is equivalent to a promise catch
    }
})()

!(async function(){
    const p5 = Promise.resolve('hello') 
    try{
        console.log('intry 2')
        const res = await p5
        console.log(res)
    }catch(err){
        console.log('p5err',err)// try... Catch is equivalent to a promise catch}})() Prints: intry1
intry 2
p4err err1
hello
Copy the code
  • Why async await should be tried.. catch?
    • Since await is equivalent to then of Promise, it does not handle catch
    • try.. Cat catches exceptions instead of the catch of Promise

The following code

! (async function(){
    const p4 = Promise.reject('err1') / / reject status
    const res = await p4 //await -> then
    console.log('res',res)
})()
// This code cannot catch exceptions
Copy the code

Nature of asynchrony

  • Async /await is the ultimate weapon against asynchronous callbacks
  • JS is still single threaded, asynchronous, and event loop-based
  • Async /await is just a syntactic candy, but this candy smells good!
Async function async1(){console.log('async1 start') //2 await async2() //await Async function async2(){console.log('async2')//3} console.log('script start') //1 Async1 () console.log('script end')//4 // Execute event loop when code is synchronizedCopy the code

for… of

  • for… In (and forEach for) is regular synchronous traversal
  • for… Of is often used for asynchronous traversal
function muti(num){ return new Promise(resolve => { setTimeout(()=>{ resolve(num * num) },1000) }) } const nums = [1,2,3] nums.foreach (async(I) => {const res =await muti[I] console.log(res)}) //for... In synchronous loop, print all results after 1 second! (async function(){ for( let i of nums){ const res = await muti(i); console.log(res) } })() //for... Of is an asynchronous loop that prints a result every secondCopy the code