js是單執行緒的,所以非同步程式設計技術對於前端來說就顯得尤為重要了,本文也是在總結前輩結果的同時儘量做到全面細緻。就當給自己做個筆記,首先我們列出非同步程式設計技術目前使用的方法,然後再對比他們之間的優缺點
回撥函式 事件監聽(事件釋出/訂閱) Promise Generator函式 async和await
1、回撥函式
ajax (url,()=>{
ajax (url1,()=>{
ajax (url2,()=>{
ajax (url3,()=>{})
})
})
})
複製程式碼
優點:簡單,容易理解 缺點: a、不利於閱讀和維護 b、容易寫出回撥地獄(callback hell) c、不能使用try catch 捕獲錯誤 d、不能直接return
2、事件監聽
IE中的監聽方法 a、obj.attachEvent('事件型別如:onclick','處理函式') b、obj.detachEvent('事件型別','處理函式') 標準DOM的事件監聽: a、obj.addEvent('事件型別如:click','處理函式','冒泡或者捕獲事件') b、obj.removeEvent('事件型別如:click','處理函式','冒泡或者捕獲事件') ⚠️:IE中的事件型別寫法和標準DO中的寫法不同前者需要寫on後者不需要。
優點:比較容易理解,可以繫結多個事件,每一個事件可以指定多個回撥函式,而且可以去耦合,有利於實現模組化。 缺點:整個程式都要變成事件驅動型,執行流程會變得不清晰。
Promise
Primise就是為了解決callback的問題產生的 優點: a、解決了回撥地獄的問題 b、實現了鏈式呼叫 缺點:無法取消Promise,錯誤需要通過回撥函式來捕獲 注意:Promise在我們構造的時候,其內部程式碼是立即執行的。
Generator
特點:可以控制函式的執行,可以配合co函式庫使用
function *fetch(){
yield agax('url1',()=>{})
yield agax('url2',()=>{})
yield agax('url3',()=>{})
}
let it=fetch()//此步驟不會執行函式
let result1=it.next()
let result2=it.next()
let result3=it.next()
複製程式碼
async/await
非同步的終極解決方案 優點:程式碼清晰,不用像Promise那樣寫一堆的.then 缺點:await將非同步程式碼改造成同步程式碼,如果多個非同步操作沒有依賴性而使用 await 會導致效能上的降低。
async function test() {
// 以下程式碼沒有依賴性的話,完全可以使用 Promise.all 的方式
// 如果有依賴性的話,其實就是解決回撥地獄的例子了
await fetch('url1')
await fetch('url2')
await fetch('url3')
}
複製程式碼