This is the 11th day of my participation in the August More Text Challenge
Single threaded and asynchronous
- Js is a single-threaded language that can only do one thing at a time
- Browsers and NodeJS already support JS startup
process
, such as a web worker - Js and DOM rendering share the same thread because JS can modify the DOM structure
- Do not get stuck when waiting (network request, scheduled task)
- Need the asynchronous
- Callback function form
Asynchronous usage scenario
- Web requests, such as Ajax, image loading
- A scheduled task, such as setTimeout
What is the difference between synchronous and asynchronous?
Based on the fact that JS is a single-threaded language, asynchrony does not block code execution, while synchronization does
Callback hell
Promise
Resolve callback hell, which can be chain-called
function getData(url){
return new Promise((resolve,reject) = >{
$.ajax({
url,
success(data){
resolve(data)
},
error(err){
reject(err)
}
})
})
}
let url1 = '/data1.json'
let url2 = '/data2.json'
let url3 = '/data3.json'
getData(url1).then(data1= >{
console.log(data1)
return getData(url2) / / promise
}).then(data2= >{
console.log(data2)
return getData(url3)
}).then(data3= >{
console.log(data3)
}).catch(err= >{
console.error(err)
})
Copy the code
What are the three states of a Promise? How does it change?
- Three states:
pending resolved rejected
- Pending -> Resolved or Pending -> Rejected
- Irreversible change
- The manifestation and change 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
- Effects of then and catch on state
- Resolved then Return Rejected when the error message is returned
Catch return resolved
If there is an error, return Rejected
//code 1
Promise.resolve().then(() = >{
console.log(1)
}).catch(() = >{
console.log(2)
}).then(() = >{
console.log(3)})// return 1, 3
// code2
Promise.resolve().then(() = >{
console.log(1)
throw new Error('error1')
}).catch(() = >{
console.log(2)
}).then(() = >{
console.log(3)})// Return 1, 2, 3
//code3
Promise.resolve().then(() = >{
console.log(1)
throw new Error('error1')
}).catch(() = >{
console.log(2)
}).catch(() = >{
console.log(3)})// return 1, 2
Copy the code
Handwriting loads an image with a Promise
const url = 'https://inews.gtimg.com/newsapp_bt/0/11327712791/641' function loadImg(src){ return new Promise((resolve,reject)=>{ const img = document.createElement('img') img.onload = ()=>{ resolve(img) } img.onerror = ()=>{const err = new Error(' Error ${SRC} ') reject(err)} img.src = SRC})} loadImg(url). Then (img=>{const err = new Error(' Error ${SRC} ') reject(err)} img.src = SRC})} loadImg(url). Log (img.width) return img // common object}).then(img=>{console.log(img.height)}).catch(ex=>console.error(ex))Copy the code
Event loop Event loop or event polling
- Js runs in a single thread
- Asynchrony is implemented based on callbacks
- 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
- Execute synchronous code first, and then execute asynchronous 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, rather than asynchronously
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
// The loadImg method is shown above Promise! (async function(){
// Syncing syntax
const img1 = await loadImg(src1)
console.log(img1.height,img1.width)
const img2 = await loadImg(src2)
console.log(img2.height,img2.width)
})()
Copy the code
Async /await and Promise relationship
- Async /await is the ultimate weapon against asynchronous callbacks
- Promise and Promise are not mutually exclusive
- The two complement each other
Executes the async function and returns a Promise object
Await is equivalent to then of Promise
try... Catch catches exceptions instead of the catch of Promise
! (async function(){
const p4 = Promise.reject('err1') / / rejected state
const res = await p4 // await -> then
console.log('res',res) / / does not perform
try{
const res = await p4
consle.log(res)
}catch(ex){
console.log(ex) // try... Catch is equivalent to a promise catch
}
//err1}) ()Copy the code
Nature of asynchrony
- Async /await is the ultimate weapon against asynchronous callbacks
- Js is still single threaded, it still has to be asynchronous, and it has to be based on event loops
- Async /await is just a syntactic sugar
'await' can be treated as' callback '
async function fn(){
return 100
}
!(async function(){
const a = fn() // Promise
const b= await fn() / / 100}) ()Copy the code
async function async1(){
console.log('async1 start') / / 2
await async2() //undefined
Callback = async; callback = async; callback = async
// Similarly, event loop,setTimeout(cb1)
// setTimeout(function(){console.log('async1 end')})
//Promise.resolve().then(()=> console.log('async1 end') )
console.log('async1 end') / / 5
}
async function async2(){
console.log('async2') / / 3
}
console.log('script start') / / 1
async1()
console.log('script end') / / 4
Copy the code
async function async1(){
console.log('async1 start') / / 2
await async2()
// The following three lines are the contents of the asynchronous callback
console.log('async1 end') / / 5
await async3()
// The next line is the content of the asynchronous callback
console.log('async1 end2') / / 7
}
async function async2(){
console.log('async2') / / 3
}
async function async3(){
console.log('async3') / / 6
}
console.log('script start') / / 1
async1()
console.log('script end') //4 After the synchronization code is executed, the event loop is executed asynchronously
Copy the code
for … Of asynchronous traversal
- 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) // One time output 1, 4, 9
})
!(async function(){
for(let i of nums){
const res =await muti(i)
console.log(res) // Outputs 1, 4, 9 every 1s
}
})()
Copy the code
MacroTash and microTask
What is a macro task? What are microtasks?
- Macro task:
SetTimeout, setInterval, Ajax, Dom events
- Micro tasks:
Promise, async/await
Microtasks are executed earlier than macro tasks
Event loop and DOM rendering
- Js is single threaded and shares a thread with DOM rendering
- While js is executing, some time is needed for DOM rendering
Execution order
- The Call Stack free
- Perform the current microtask
- Try DOM rendering
- Trigger Event loop
Why do microtasks execute earlier than macro tasks
- Call Each time the Stack is cleared (that is, each poll ends), the synchronization task is complete
- Both are opportunities to re-render the DOM, and re-render if the DOM structure changes
- Then the next Event loop is triggered
Alert blocks JS execution as well as DOM rendering
The difference between microtasks and macro tasks
- Macro task:
Triggered after DOM rendering
Such as setTimeout; Is specified by the browser - Micro tasks:
Triggered before DOM rendering
, such as a Promise; ES6
async function async1(){
console.log('async1 start') / / 2
await async2()
//await everything after that 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 function 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