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