Promise、async/await實現非同步操作
阿新 • • 發佈:2022-03-19
併發與並行
- 併發:對於單核處理器,同一時間內多個程式同時進行,這些程式在微觀上是交替進行的
- 並行:對於多核處理器,同一時刻內有多個程式同時進行
同步與非同步
- 同步 Synchronous :前一個任務執行完畢後,後一個任務才能進行。
- 非同步 Asynchronous:多個任務可同時進行——多執行緒程式設計
JavaScript沒有多執行緒概念,而是通過函式回撥實現單執行緒“併發”。比如通過fetch獲取網路資源,獲取過程先會被跳過,去執行其他任務,等資源獲取完畢後再執行回撥函式。即在同一個執行緒中,要等待的任務先讓不需等待的任務執行,直到等待完獲取到資源後,再插隊進來。
setTimeout()實現非同步
setTimeout(()=>{
console.log('三秒後執行')
},3000)
//面臨“回撥地域” CallBack Hell 問題
setTimeout(()=>{
console.log('三秒後執行')
setTimeout(()=>{
console.log('三秒後執行')
setTimeout(()=>{
console.log('三秒後執行')
},3000)
},3000)
},3000)
Promise實現非同步
能夠通過鏈式結構將多個非同步操作串聯起來,而不需要多層巢狀
- 方法:then、catch、all、finally
const goal=70 const result = new Promise((resolve,reject)=>{ if (goal>=60){ resolve('良好') }else{ reject('不及格') } }) result.then(e=>{ console.log('你通過了考試!') }).catch(e=>{ console.log('非常遺憾,你未能通過考試!') }).finally(()=>{ console.log('感謝你參與本次測試!') })
async/await與promise
-
async表明了某函式的返回值是非同步物件(如promise物件)
async function f(){/*返回非同步物件promise*/} //such as async function f(){ return new Promise((resolve,reject)=>{/*...*/}) }
-
await常跟著一個promise物件,等待非同步執行
async function getResult(){ const response=await fetch('...') //fetch返回的是非同步物件 text=response.json() console.log(text) }
多個非同步操作
- forEach會立刻執行,下面寫法會直接跳到
console.log
,所以forEach無法實現非同步。async function f(){ [1,2,3].forEach(async i =>{ await someAsyncOperations() }) console.log('完成啦') }
- 可以用for迴圈實現非同步
async function f(){ for(let i of [1,2,3]){ await someAsyncOperations() } console.log('完成啦') }
- 升級版,
for await
非同步併發。async function f(){ const promises=[ someAsyncOperations(), someAsyncOperations(), someAsyncOperations() ] for await (let result of promises){ // } console.log('完成啦') }
Await和Async
- async函式內如果碰到await,會等待非同步完成後再執行下一個函式
async function getStockPriceByName(name) { let symbol = await getStockSymbol(name); let stockPrice = await getStockPrice(symbol); return stockPrice; //返回promise物件 } getStockPriceByName('goog').then(()=>{/*...*/})
- async函式的return會成為then回撥的引數
async function f() { return 'hello world'} f().then(v => console.log(v))
- await後面的結果如果是reject,會終止程式。如果想繼續,用
try catch
async function f() { try { await Promise.reject('出錯了'); } catch(e) { console.log('出錯了') } return await Promise.resolve('hello world'); } f() .then(v => console.log(v))