非同步處理方法

gujianxin發表於2019-02-21

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')
}
複製程式碼

相關文章