Skip to content

Commit 98e3bcb

Browse files
committed
docs: edit async-iterator
1 parent 6545088 commit 98e3bcb

File tree

2 files changed

+69
-2
lines changed

2 files changed

+69
-2
lines changed

docs/async-iterator.md

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,75 @@
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

774
ES2018 [引入](https://github.com/tc39/proposal-async-iteration)了“异步遍历器”(Async Iterator),为异步操作提供原生的遍历器接口,即`value``done`这两个属性都是异步产生。
875

sidebar.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@
2626
1. [Generator 函数的语法](#docs/generator)
2727
1. [Generator 函数的异步应用](#docs/generator-async)
2828
1. [async 函数](#docs/async)
29-
1. [异步遍历器](#docs/async-iterator)
3029
1. [Class 的基本语法](#docs/class)
3130
1. [Class 的继承](#docs/class-extends)
3231
1. [Module 的语法](#docs/module)
3332
1. [Module 的加载实现](#docs/module-loader)
3433
1. [编程风格](#docs/style)
3534
1. [读懂规格](#docs/spec)
35+
1. [异步遍历器](#docs/async-iterator)
3636
1. [ArrayBuffer](#docs/arraybuffer)
3737
1. [最新提案](#docs/proposals)
3838
1. [Decorator](#docs/decorator)

0 commit comments

Comments
 (0)