async await 真不是你想象中那麼簡單

2021-09-14 01:09:29 字數 3206 閱讀 8148

先上**

function getdata(data, time) , time)})}

let results = ;

let starttime = new date();

laucher();

async function laucher() 在$毫秒放入`);

let datab = await getdata('b', 3000);

results.push(`$在$毫秒放入`);

let datac = await getdata('c', 1000);

results.push(`$在$毫秒放入`);

console.log(results, `輸出時間$毫秒`);

}

輸出

["a在2002毫秒放入", "b在5004毫秒放入", "c在6006毫秒放入"] "輸出時間6006毫秒"
async function laucher() 毫秒`);

}

輸出

["a", "b", "c"] "輸出時間3006毫秒"
async function laucher() 在$毫秒放入`);

datab = await databpromise;

results.push(`$在$毫秒放入`);

datac = await datacpromise;

results.push(`$在$毫秒放入`);

console.log(results, `輸出時間$毫秒`);

}

輸出

["a在2003毫秒放入", "b在3001毫秒放入", "c在3001毫秒放入"] "輸出時間3002毫秒"
async function laucher() 在$毫秒放入`);

})();

(async () => 在$毫秒放入`);

console.log(results, `輸出時間$毫秒`);//results放在最後返回的請求中

})();

(async () => 在$毫秒放入`);

})();

}

輸出

["c在1002毫秒放入", "a在2002毫秒放入", "b在3003毫秒放入"] "輸出時間3003毫秒"
使用settimeout模擬了3條非同步請求,分別2000,3000,1000毫秒後返回'a', 'b', 'c',

第一種方法很好理解,就是一步一步執行,這種方法適合請求引數依賴上乙個請求返回值的情況,在這裡是不存在這種關係的,也就是這種方法在這裡效率是比較低的。

第二種方法一開始就發起了3個請求,並等待3請求都到達後獲取資料。

第三種方法也一開始就發起了3個請求,並在請求到達後依次執行,因為a請求到達時間是2秒,a請求到達後,把a的結果推入results,再往下執行,b請求是3秒,b請求遲a請求一秒到達,也就是再過一秒後把b的結果推入results,,c的請求是1秒,這個時候c早已到達,在這輪迴圈末尾可以立即把c推入。a請求返回的資料2秒後就能操作了,這種方法比第二種方法可以更快處理資料。如果請求時間是依次遞減的,那麼和方法二效果是一樣,在有多個請求時這種情況一般不存在。

第四種方法和第三種方法的區別是最先到達的請求最快放入結果集,也就是我不用排隊等待處理,哪個資料先返回我就先處理哪個資料,假如c請求返回的資料需要花比較長的時間處理,我在一秒後就能開始處理了,但是第三種方法我得3秒後才能開始處理。可以看到我把results的輸出放在了b請求到達的函式中,因為results在最後乙個請求到達後才能完整輸出,與方法三的區別是獲取結果的操作也是非同步的,這個很關鍵,也是和方法三最大的區別,通過在外層包裝乙個自執行函式,可以防止await的操作權跳出laucher外部,從而併發發起3個獲取結果的操作。可能大家會有疑問假如我不清楚哪個請求最後到達,那怎麼獲取最後的results值,這種情況可以在外麵包乙個promise.all,可以仔細看一下下面兩個函式的區別

async function laucher() 毫秒`);

}

輸出

["a", "b", "c"] "輸出時間3003毫秒"
async function laucher() 在$毫秒輸出`);

//這裡可以提前處理資料

return data

}));

console.log(results);

}

輸出

c在1002毫秒輸出

a在2003毫秒輸出

b在3003毫秒輸出

["a", "b", "c"] "輸出時間3004毫秒"

如果請求之間不存在繼發關係,並且請求到達後要執行一些運算,那麼按效率來說

方法4 > 方法3 > 方法2 > 方法1

每種方法都對應一種載入的策略,以乙個使用場景來說明一下,向後台載入頁面元件(假設元件個數是3)

執行流程:

方法一: 發起元件1的請求 -> 元件1資料到達後渲染元件1 -> 發起元件2的請求 -> 元件2資料到達後渲染元件2 -> 發起元件3的請求 -> 元件3資料到達後渲染元件3

方法二: 同時發起元件1,2,3的請求 -> 元件1,2,3的資料都到達後渲染元件1,2,3

方法三: 同時發起元件1,2,3的請求 -> 元件1資料到達後渲染元件1 -> 元件2資料到達後渲染元件2 -> 元件3資料到達後渲染元件3

方法四: 同時發起元件1,2,3的請求 -> 最快到達的元件資料到達後渲染最快到達的元件 -> 第二快到達的元件資料到達後渲染第二快到達的元件 -> 最慢到達的元件資料到達後渲染最慢到達的元件

針對以上場景可以看出方法四可以讓我們的頁面最快渲染出內容

可以看出雖然引入async/await,可以讓你的**很精簡,但是async/await本身的執行流程卻是很複雜的,下面的**你可以猜一下輸出結果(補充一點:有的文章會指出foreach函式不能放入非同步操作,這種結論是錯誤的,如果是繼發關係確實不適宜用foreach,但不能表示不能放入非同步操作,反而這種操作能提高獲取資料的效率)

[1, 2].foreach(async function (value) )

console.log(3);

CRA 黑盒真不是你想的那麼可怕

前兩篇內容 今天這篇文章我們繼續談談 cra 黑盒的實現。在專案開發中,我們把它分成三份 乙份是是專案結構,乙份是黑盒,乙份是最終的產出。簡單來說,寫好後的專案,經過黑盒處理之後,就成了乙個可以上線部署的產品。這個處理過程就需要前端開發者們去努力實現了。黑盒其實很簡單,就是需要我們打破平時的開發思維...

談加薪,真不是漲點錢那麼簡單

2018年只剩6周了,很多人心裡開始琢磨加薪的事情。然後,談加薪,真不是找老闆說一句話那麼簡單的事兒,它是乙個系統工程。這裡面有 4 個關鍵部分要留意 簡要說下。公司給你加薪,一般是因為 所以,加薪時,羅列的理由,最好是不可辯駁的事實。比如 這樣子的理由,都是事實,好談。一般不要以諸如我生孩子了 買...

重頭再來,真不是說著玩

今天見鬼了 原因是之前安裝的環境是centos6.8,用到後面發現6.8不能滿足後續docker的效能,那就接受這個現實吧!其實,這個問題貌似也能避免,繼續使用 於是,我重新安裝虛擬機器環境,換成centos7.4的,從6.8的桌面版本,變到了非桌面版本,看著怪怪的。沒事,這個我也不是不能接受,於是...