1. 程式人生 > 程式設計 >關於對async await效率問題的深入思考

關於對async await效率問題的深入思考

關於async await

async await於ES2017標準引入,本身的功能是作為語法糖簡化寫法的。

下面列舉一個使用promise的例子:

 function myPromise(flag) {
     return new Promise((resolve,reject) => {
         if (flag) {
             return resolve(flag)
         } else {
             return reject('error')
         }
     })
 }
 // 在p1的回調呼叫p2
 const p1 = myPromise(1)
 p1.then(v => {
     const p2 = myPromise(2)
     p2.then(v => {
         console.log(v)
     })
 })

因為p2的引數與p1的返回值有關這個例子確保了p2在p1的promise為成功的情況下再呼叫,確保了呼叫的順序,如果只有少許的順序要求,實現起來結構還不至於非常複雜,如果後續需要確保多個promise的呼叫順序,那麼就會有很多層.then去呼叫promise會導致程式碼巢狀太多,可讀性差。

async await的出現解決了程式碼可讀性的問題。

下面是一個例子:

 function myPromise(flag) {
     return new Promise((resolve,reject) => {
         if (flag) {
             return resolve(flag)
         } else {
             return reject('error')
         }
     })
 }
 let v
 const p1 = await myPromise(1)
 p1.then(val => { v = val }) 
 const p2 = await myPromise(v)
 p2.then(val => { v = val })
 const p3 = await myPromise(v)
 p3.then(val => { v = val })
 const p4 = await myPromise(v)
 p4.then(val => { v = val })
 const p5 = await myPromise(v)
 p5.then(val => { v = val })
 const p6 = await myPromise(v)
 p6.then(val => { v = val })
 const p7 =  myPromise(v)

這樣就可以不依靠大量的.then巢狀去確保非同步方法的呼叫順序。

效率問題的思考

下面給大家看一段虛擬碼:

 function getData(url) {
     return url
 }
 ​
 function postDatuutQea(url) {
     console.log(url)
 }
 ​
 let data1 = await getData('/xxx') // 操作1 需要花費10s
 let data2 = await getData('/xxx') // 操作2 需要花費10s
 postData(data1 + '/xxx') // 操作3 需要花費20s
 postData(data2 + '/yyy') // 操作4 需要花費5s

熟悉事件迴圈的同學應該能很快求出執行所需的時間,總共需要40s去執行,那麼對於這個虛擬碼我們可以做出優化嗎?答案是可以的。

下面看一下優化後的程式碼:

 function getData(url)客棧 {
     return url
 }
 ​
 function postData(url) {
     console.log(url)
 }
 ​
 let data1 = await getData('/xxx') // 操作1 需要花費10s
 postData(data1 + '/xxx') // 操作4 需要花費20s
 let data2 = await getData('/xxx') // 操作2 需要花費10s
 postData(data2 + '/yyy') // 操作3 需要花費5s

這樣的話執行時間就被優化到了30s,我們可以看一下二者的執行時的對比:

第一個方式

關於對asyncawait效率問題的深入思考

第二個方式

關於對asyncawait效率問題的深入思考

所以當我們使用async await時還是要去注意一下非同步程式碼的呼叫順序,適當的優化可以減少程式的執行時間,而且程式設計客棧我們應正確的使用async await語法糖,只有後續操作需要用到非同步請求所得到的資料時才需要為非同步請求加上await修飾確保資料能夠獲取,否則不需要加await修飾。

後續

雖然可能大家覺得這個題目比較標題黨,但我沒有要深度剖析的意思,只是想交流討論一下,希望大家的評論還是客氣一點。 關於評論區有掘友指出我的理解有問題,這裡我用setTimeout控制一下Promise的返回時間,程式碼如下

function t5s() {
    return new Promise((resolve,reject) => {
        setTimeout(() => {
            resolve(1)
            console.log('5s')
        },5000);
    })
}
function t3s() {
    return new Promise((resolve,reject) => {
        setTimeout(() => {
            resolve(1)
            console.log('3s')
        },3000);
    })
}
function t2s() {
    return new Promise((resolve,reject) => {
        setTimeout(() => {
            resolve(1)
            console.log('2s')
        },2000);
    })
}
/* 
    這裡應該是等待5s後返回第一個Promise並列印5s,然後再等待3s後返回第二個Promise並列印3s,
    最後再等待2s後返回第三個Promise並列印2s,總用時10s
*/
(async () => {
    await t5s()
    await t3s()
    await t2s()
})()
/*
    這裡我的理解是3個操作會依次進入微任務池中依次執行,因此2s後列印2s,3s後列印3s,5s後列印5s,總用時5s
*/
(() => {
    t5s()
    t3s()
    t2s()
})()

總結

到此這篇關於對asyncawahttp://www.cppcns.comit效率問題的深入思考的文章就介紹到這了,更多相關asyncawait效率問題內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!