嘿,大家好!javascript
幾個月前,Deno--一種Node.js的後繼者--發佈了,在主頁上有一個如何使用它的小演示。java
import { serve } from "https://deno.land/std@0.69.0/http/server.ts"; const s = serve({ port: 8000 }); console.log("http://localhost:8000/"); for await (const req of s) { req.respond({ body: "Hello Worldn" }); }
忽然,當看到第4行的await調用在for以後,但在(const req of s)以前時,個人眼睛就 "那是什麼?"?node
我歷來沒有見過這樣的東西,個人第一個想法是 "這是一個很是酷和奇怪的事情,deno作"....。python
想象一下個人驚訝,當我閱讀了更多關於deno的資料後,我發現那一小段代碼實際上是有效的javascript,並且_它在Node.js中也是有效的,而我對它一無所知_。設計模式
那麼,這是什麼呢,爲何我歷來沒有見過,我應該用在哪裏呢,我是否是已經錯過了?數組
若是你也有一樣的疑問,那麼好!dom
這篇文章將嘗試回答這些問題!異步
首先,先說一下。async
你見過這樣的東西嗎?函數
class RandomNumberGenerator { [Symbol.iterator]() { return { next: () => { return { value: Math.random() }; }, }; } }
若是你作了,那麼對你來講很好,你能夠跳到下一節!
若是你尚未,那麼讓咱們深刻了解一下這個類的做用。
這個類RandomNumberGenerator
實現了[Symbol.iterator]
或@@iterator
方法(當該方法經過Symbol屬性定義時,咱們用雙@@
來表示該方法)。
當[Symbol.iterator]
或@@iterator
方法定義在一個對象上時,容許對象進行迭代!
因爲如今咱們將@@iterator
方法定義爲RandomNumberGenerator類的一個實例方法,因此這個類的全部實例如今都是可迭代的。如今你能夠經過運行下面的代碼來測試它。
class RandomNumberGenerator { [Symbol.iterator]() { return { next: () => { return { value: Math.random() }; }, }; } } const rand = new RandomNumberGenerator(); for (const random of rand) { console.log(random); if (random < 0.1) break; }
爲了讓一切都能正常工做,"@@iterator "方法必須返回一個包含 "next "方法的對象,而且 "next "方法須要返回另外一個具備 "value "和 "done "屬性的對象。
value
將包含返回的值,而done
將是一個布爾值,若是它被設置爲true將結束迭代。
雖然 "value "是必須的,但 "done "能夠省略,就像上面的例子同樣(這容許咱們定義_無限的迭代)。
好吧,酷!咱們如今可讓事情變得可迭代了。
咱們如今可讓事情變得可迭代了!
這在何時纔有用呢?
我相信這高度依賴於你正在建立的業務邏輯的類型。
例如Node.js設計模式這本書--我強烈推薦--給出了一個迭代矩陣元素的例子(你可能已經把它定義爲一個數組)。
另外我相信這篇文章強調了一些很酷的用法。它定義了一些很是酷的方法,看起來頗有python風格。
然而,若是你想知道個人誠實和我的意見,我尚未遇到過 "這是迭代器的一個偉大的用例 "的狀況。
不管如何,讓咱們回到咱們文章的主題:咱們還須要在for循環中添加 await什麼?
顧名思義,異步迭代器是咱們在上面的例子中所作的異步版本。
想象一下,咱們不是返回一個隨機數,而是返回承諾。那會是怎樣的呢?
若是咱們把上面的例子改爲這樣,它就會是這樣的。
const simulateDelay = (val, delay) => new Promise((resolve) => setTimeout(() => resolve(val), delay)); class RandomNumberGenerator { [Symbol.asyncIterator]() { return { next: async () => { return simulateDelay({ value: Math.random() }, 200); //return the value after 200ms of delay }, }; } } const rand = new RandomNumberGenerator(); (async () => { for await (const random of rand) { console.log(random); if (random < 0.1) break; } })();
變化有哪些?
因而咱們作了一個簡單的程序,可以對一個對象進行迭代,以異步的方式獲取其元素。
若是你知道除了主頁上的小deno例子以外,還有其餘的異步迭代器的實現,請發郵件給我,或者在下面留言