- 原文地址:Javascript - Generator-Yield/Next & Async-Await
- 原文做者:Deepak Gupta
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:iceytea
- 校對者:huimingwu, zsky
Generator (ES6)javascript
generator 函數是一個能夠根據用戶需求,在不一樣的時間間隔返回多個值,並能管理其內部狀態的函數。若是一個函數使用了 function* 語法,那麼它就變成了一個 generator 函數。前端
它們與正常函數不一樣,正常函數在單次執行中完成運行,而 generator 函數能夠被暫停和恢復。它們確實會運行完成,但觸發器在咱們手中。它們使得對異步函數能有更好的執行控制,但這並不意味着它們不能用做同步函數。java
注意:執行 generator 函數時,會返回一個新的 Generator 對象。node
generator 的暫停和恢復是使用 yield
和 next
完成的。讓咱們來看看它們是什麼,以及它們能作什麼。android
yield
關鍵字暫停 generator 函數的執行,而且yield
關鍵字後面的表達式的值將返回給 generator 的調用者。它能夠被理解爲基於 generator 版本的return
關鍵字。ios
yield
關鍵字實際上返回一個具備 value
和 done
兩個屬性的 IteratorResult
對象。(若是你不瞭解什麼是 iterators 和 iterables,點擊這裏閱讀)。git
一旦暫停
yield
表達式,generator 的代碼執行將保持暫停狀態,直到調用 generator 的next()
方法爲止。每次調用 generator 的next()
方法時,generator 都會恢復執行並返回 iterator 結果。es6
嗯……理論先到這裏,讓咱們看一個例子:github
function* UUIDGenerator() {
let d, r;
while(true) {
yield 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
r = (new Date().getTime() + Math.random()*16)%16 | 0;
d = Math.floor(d/16);
return (c=='x' ? r : (r&0x3|0x8)).toString(16);
});
}
};
複製代碼
UUIDGenerator 是一個 generator 函數,它使用當前時間和隨機數計算 UUID ,並在每次執行時返回一個新的 UUID 。redux
要運行上面的函數,咱們須要建立一個能夠調用 next()
的 generator 對象:
const UUID = UUIDGenerator();
// UUID is our generator object
UUID.next()
// return {value: 'e35834ae-8694-4e16-8352-6d2368b3ccbf', done: false}
複製代碼
每次 UUID.next() 返回值的 value 值是新的 UUID ,done 值將始終爲 false ,由於咱們處於一個無限循環中。
注意:咱們在無限循環上暫停,這是一種很酷的方式。在 generator 函數中的任何「中止點」處,不只能夠爲外部函數生成值,還能夠從外部接收值。
有許多 generator 的實現,而且不少庫都在大量使用。好比說 co、koa 和 redux-saga。
依照慣例,當一個異步操做返回由 Promise
處理的數據時,回調會被傳遞並調用。
Async/Await 是一種特殊的語法,以更溫馨的方式使用 Promise,這種方式很是容易理解和使用。
Async 關鍵字用於定義異步函數 ,該函數返回一個 AsyncFunction 對象。
Await 關鍵字用於暫停異步函數執行,直到 Promise
被解決(resolved 或者 rejected),並在完成後繼續執行 async
函數。恢復時,await 表達式的值是已執行的 Promise 的值。
關鍵點:
- Await 只能在異步函數中使用。
- 具備 async 關鍵字的函數將始終返回 promise。
- 在相同函數下的多個 await 語句將始終按順序運行。
- 若是 promise 正常被 resolve,則
await
會返回promise
結果。可是若是被 reject,它就會拋出錯誤,就像在那行有throw
語句同樣。- 異步函數不能同時等待多個 promise。
- 若是在 await 以後使用 await 屢次,而且後一條語句不依賴於前一條語句,則可能會出現性能問題。
到目前爲止一切順利,如今讓咱們看一個簡單的例子:
async function asyncFunction() {
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("i am resolved!"), 1000)
});
const result = await promise;
// wait till the promise resolves (*)
console.log(result); // "i am resolved!"
}
asyncFunction();
複製代碼
在 await promise
這一行,asyncFunction
執行「暫停」,並在 promise 被解決後回覆,result
(第 95 行的 const result
)變成它的結果。上面的代碼在一秒鐘後展現 「i am resolved!
」。
next
方法),而 Async-await 按照 await 接着 await 的順序依序執行。若是您想要添加到個人電子郵件列表中,請考慮 在此處輸入您的電子郵件,並在 medium 上關注我以閱讀更多有關 javascript 的文章,並在 github 上查看個人瘋狂代碼。若是有什麼不清楚的,或者你想指出什麼,請在下面評論。
你可能也喜歡個人其餘文章:
若是你喜歡這篇文章,請鼓掌。提示:你能夠拍 50 次!此外,歡迎推薦和分享,以幫助其餘人找到它!
謝謝!
若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。