什麼是Async/Awaitjavascript
ES6新增了Promise函數用於簡化項目代碼流程。然而在使用promise時,咱們仍然要使用callback,而且並不知道程序要幹什麼,例如:java
function doSomething() { let i = 0; waitOneSecond() // 返回一個Promise對象
.then(() => console.log(i)); i = 5; }
最終console.log(i) 的結果是5,並非0數據庫
爲此,ES7引入了async函數,前面的例子能夠改寫這樣:設計模式
async function doSomething() { let i = 0; await waitOneSecond();// 等待1秒 console.log(i); i = 5; }
這段代碼片斷中console.log(i)的結果是0。其中關鍵字await中止當前函數的執行,直到waitOneSecond()返回的promise對象狀態變動爲fulfilled(完成),併產生其返回值。數組
當返回的promise對象的狀態變動爲rejected(失敗),錯誤信息會被 try/catch 代碼塊所捕獲。promise
常見陷阱async
效率損失:函數
亂用async/await,可能致使低效的設計模式。例如,假設咱們想從數據庫中得到一些用戶他們的年齡平均。咱們會這樣作的:性能
async function getUserAge(userId) { await waitOneSecond();// 等待1秒 return 7; } async function getAverageAge(userIds) { let sumOfAges = 0; let numOfUsers = userIds.length; for (let userId of userIds) { sumOfAges += await getUserAge(userId); } return sumOfAges / numOfUsers; }
顯而易見,這是錯誤的,假設咱們有5個用戶,上面的代碼片斷會輪訓全部的用戶而且等待每個單獨調用數據庫,因此最終整個函數的等待時間是5秒。spa
爲了更好的性能,下降等待時間,修改以下:
async function getAverageAge(userIds) { let sumOfAges = 0; let numOfUsers = userIds.length;
let agesPromises = userIds.map(getUserAge);//將每一個用戶對應的promise對象封裝到數組中 let ages = await Promise.all(agesPromises);//使用Promise.all調用 for (let age of ages) { sumOfAges += age; } return sumOfAges / numOfUsers; }
修改以後,代碼變得複雜了一些,可是全部的數據庫調用,都是同時進行的。不管你有多少用戶,這個方法的等待時間只須要1秒。
在使用async/await函數時,當函數體內須要使用await屢次調用外部函數而且函數返回值彼此無依賴關係時,使用Promise.all下降函數總體的等待時間。
變量污染:
當使用async函數時,會令代碼更易閱讀,可是他們並非真正的將你的代碼變爲同步,只是promise的語法糖而已,看下面這個例子
let currentUserId = 0; async function getInfoAboutUser() { currentUserId++; // 令每一個用戶id均惟一
let data = await waitTenSeconds(); // 獲取某些其餘數據,等待時間10秒
return { id: currentUserId , data }; } async function registerUser() { let user = await getInfoAboutUser(); await storeUser(user); }
如今假設,有2個不一樣的用戶接連註冊,getInfoAboutUser 函數將被接連執行,當10秒的等待時間結束後,2個用戶的id都是相同的。
在這個例子中,咱們能夠很簡單的避免這個問題:
async function getInfoAboutUser() { let data = await waitTenSeconds(); // 獲取某些其餘數據,等待時間10秒
currentUserId++; //令每一個用戶id均惟一
return { id: currentUserId }; }
結語
async/await函數的出現,極大的提升了javascript代碼的可讀性,可是他們並非魔法,依然有不少未知的問題等待咱們去發現。
我但願你喜歡這篇文章,並認爲它游泳。若是有其餘的陷阱,或者有任何疑問,請在評論中讓我知道