嘿,大家好!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例子以外,还有其余的异步迭代器的实现,请发邮件给我,或者在下面留言