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