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 1
1
# 异步遍历器
2
2
3
+ ## 同步遍历器的问题
4
+
3
5
《遍历器》一章说过,Iterator 接口是一种数据遍历的协议,只要调用遍历器对象的` next ` 方法,就会得到一个对象,表示当前遍历指针所在的那个位置的信息。` next ` 方法返回的对象的结构是` {value, done} ` ,其中` value ` 表示当前的数据的值,` done ` 是一个布尔值,表示遍历是否结束。
4
6
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 对象,用来放置异步操作。但是这样写很麻烦,不太符合直觉,语义也比较绕。
6
73
7
74
ES2018 [ 引入] ( https://github.com/tc39/proposal-async-iteration ) 了“异步遍历器”(Async Iterator),为异步操作提供原生的遍历器接口,即` value ` 和` done ` 这两个属性都是异步产生。
8
75
Original file line number Diff line number Diff line change 26
26
1 . [ Generator 函数的语法] ( #docs/generator )
27
27
1 . [ Generator 函数的异步应用] ( #docs/generator-async )
28
28
1 . [ async 函数] ( #docs/async )
29
- 1 . [ 异步遍历器] ( #docs/async-iterator )
30
29
1 . [ Class 的基本语法] ( #docs/class )
31
30
1 . [ Class 的继承] ( #docs/class-extends )
32
31
1 . [ Module 的语法] ( #docs/module )
33
32
1 . [ Module 的加载实现] ( #docs/module-loader )
34
33
1 . [ 编程风格] ( #docs/style )
35
34
1 . [ 读懂规格] ( #docs/spec )
35
+ 1 . [ 异步遍历器] ( #docs/async-iterator )
36
36
1 . [ ArrayBuffer] ( #docs/arraybuffer )
37
37
1 . [ 最新提案] ( #docs/proposals )
38
38
1 . [ Decorator] ( #docs/decorator )
You can’t perform that action at this time.
0 commit comments