File tree Expand file tree Collapse file tree 2 files changed +69
-2
lines changed Expand file tree Collapse file tree 2 files changed +69
-2
lines changed Original file line number Diff line number Diff line change 11# 异步遍历器
22
3+ ## 同步遍历器的问题
4+
35《遍历器》一章说过,Iterator 接口是一种数据遍历的协议,只要调用遍历器对象的` next ` 方法,就会得到一个对象,表示当前遍历指针所在的那个位置的信息。` next ` 方法返回的对象的结构是` {value, done} ` ,其中` value ` 表示当前的数据的值,` done ` 是一个布尔值,表示遍历是否结束。
46
5- 这里隐含着一个规定,` next ` 方法必须是同步的,只要调用就必须立刻返回值。也就是说,一旦执行` next ` 方法,就必须同步地得到` value ` 和` done ` 这两个属性。如果遍历指针正好指向同步操作,当然没有问题,但对于异步操作,就不太合适了。目前的解决方法是,Generator 函数里面的异步操作,返回一个 Thunk 函数或者 Promise 对象,即` value ` 属性是一个 Thunk 函数或者 Promise 对象,等待以后返回真正的值,而` done ` 属性则还是同步产生的。
7+ ``` javascript
8+ function idMaker () {
9+ let index = 0 ;
10+
11+ return {
12+ next : function () {
13+ return { value: index++ , done: false };
14+ }
15+ };
16+ }
17+
18+ const it = idMaker ();
19+
20+ it .next ().value // 0
21+ it .next ().value // 1
22+ it .next ().value // 2
23+ // ...
24+ ```
25+
26+ 上面代码中,变量` it ` 是一个遍历器(iterator)。每次调用` it.next() ` 方法,就返回一个对象,表示当前遍历位置的信息。
27+
28+ 这里隐含着一个规定,` it.next() ` 方法必须是同步的,只要调用就必须立刻返回值。也就是说,一旦执行` it.next() ` 方法,就必须同步地得到` value ` 和` done ` 这两个属性。如果遍历指针正好指向同步操作,当然没有问题,但对于异步操作,就不太合适了。
29+
30+ ``` javascript
31+ function idMaker () {
32+ let index = 0 ;
33+
34+ return {
35+ next : function () {
36+ return new Promise (function (resolve , reject ) {
37+ setTimeout (() => {
38+ resolve ({ value: index++ , done: false });
39+ }, 1000 );
40+ });
41+ }
42+ };
43+ }
44+ ```
45+
46+ 上面代码中,` next() ` 方法返回的是一个 Promise 对象,这样就不行,不符合 Iterator 协议。也就是说,Iterator 协议里面` next() ` 方法只能包含同步操作。
47+
48+ 目前的解决方法是,将异步操作包装成 Thunk 函数或者 Promise 对象,即` next() ` 方法返回值的` value ` 属性是一个 Thunk 函数或者 Promise 对象,等待以后返回真正的值,而` done ` 属性则还是同步产生的。
49+
50+ ``` javascript
51+ function idMaker () {
52+ let index = 0 ;
53+
54+ return {
55+ next : function () {
56+ return {
57+ value: new Promise (resolve => setTimeout (() => resolve (index++ ), 1000 )),
58+ done: false
59+ };
60+ }
61+ };
62+ }
63+
64+ const it = idMaker ();
65+
66+ it .next ().value .then (o => console .log (o)) // 1
67+ it .next ().value .then (o => console .log (o)) // 2
68+ it .next ().value .then (o => console .log (o)) // 3
69+ // ...
70+ ```
71+
72+ 上面代码中,` value ` 属性的返回值是一个 Promise 对象,用来放置异步操作。但是这样写很麻烦,不太符合直觉,语义也比较绕。
673
774ES2018 [ 引入] ( https://github.com/tc39/proposal-async-iteration ) 了“异步遍历器”(Async Iterator),为异步操作提供原生的遍历器接口,即` value ` 和` done ` 这两个属性都是异步产生。
875
Original file line number Diff line number Diff line change 26261 . [ Generator 函数的语法] ( #docs/generator )
27271 . [ Generator 函数的异步应用] ( #docs/generator-async )
28281 . [ async 函数] ( #docs/async )
29- 1 . [ 异步遍历器] ( #docs/async-iterator )
30291 . [ Class 的基本语法] ( #docs/class )
31301 . [ Class 的继承] ( #docs/class-extends )
32311 . [ Module 的语法] ( #docs/module )
33321 . [ Module 的加载实现] ( #docs/module-loader )
34331 . [ 编程风格] ( #docs/style )
35341 . [ 读懂规格] ( #docs/spec )
35+ 1 . [ 异步遍历器] ( #docs/async-iterator )
36361 . [ ArrayBuffer] ( #docs/arraybuffer )
37371 . [ 最新提案] ( #docs/proposals )
38381 . [ Decorator] ( #docs/decorator )
You can’t perform that action at this time.
0 commit comments