1
0
mirror of https://github.com/ruanyf/es6tutorial.git synced 2025-05-24 18:32:22 +00:00

docs(generator): edit Generator

This commit is contained in:
ruanyf 2017-09-06 11:41:09 +08:00
parent ba08efe8d1
commit 4dbd9b0f48

View File

@ -265,6 +265,27 @@ b.next(13) // { value:42, done:true }
注意,由于`next`方法的参数表示上一个`yield`表达式的返回值,所以在第一次使用`next`方法时传递参数是无效的。V8 引擎直接忽略第一次使用`next`方法时的参数,只有从第二次使用`next`方法开始,参数才是有效的。从语义上讲,第一个`next`方法用来启动遍历器对象,所以不用带有参数。
再看一个通过`next`方法的参数,向 Generator 函数内部输入值的例子。
```javascript
function* dataConsumer() {
console.log('Started');
console.log(`1. ${yield}`);
console.log(`2. ${yield}`);
return 'result';
}
let genObj = dataConsumer();
genObj.next();
// Started
genObj.next('a')
// 1. a
genObj.next('b')
// 2. b
```
上面代码是一个很直观的例子,每次通过`next`方法向 Generator 函数输入值,然后打印出来。
如果想要第一次调用`next`方法时,就能够输入值,可以在 Generator 函数外面再包一层。
```javascript
@ -287,27 +308,6 @@ wrapped().next('hello!')
上面代码中Generator 函数如果不用`wrapper`先包一层,是无法第一次调用`next`方法,就输入参数的。
再看一个通过`next`方法的参数,向 Generator 函数内部输入值的例子。
```javascript
function* dataConsumer() {
console.log('Started');
console.log(`1. ${yield}`);
console.log(`2. ${yield}`);
return 'result';
}
let genObj = dataConsumer();
genObj.next();
// Started
genObj.next('a')
// 1. a
genObj.next('b')
// 2. b
```
上面代码是一个很直观的例子,每次通过`next`方法向 Generator 函数输入值,然后打印出来。
## for...of 循环
`for...of`循环可以自动遍历 Generator 函数时生成的`Iterator`对象,且此时不再需要调用`next`方法。
@ -706,6 +706,44 @@ g.next() // { value: 7, done: true }
上面代码中,调用`return`方法后,就开始执行`finally`代码块,然后等到`finally`代码块执行完,再执行`return`方法。
## next()、throw()、return() 的共同点
网友 vision57 提出,`next()``throw()``return()`这三个方法本质上是同一件事,可以放在一起理解。它们的作用都是让 Generator 函数恢复执行,并且使用不同的语句替换`yield`表达式。
`next()`是将`yield`表达式替换成一个值。
```javascript
const g = function* (x, y) {
let result = yield x + y;
return result;
};
const gen = g(1, 2);
gen.next(); // Object {value: 3, done: false}
gen.next(1); // Object {value: 1, done: true}
// 相当于将 let result = yield x + y
// 替换成 let result = 1;
```
上面代码中,第二个`next(1)`方法就相当于将`yield`表达式替换成一个值`1`。如果`next`方法没有参数,就相当于替换成`undefined`
`throw()`是将`yield`表达式替换成一个`throw`语句。
```javascript
gen.throw(new Error('出错了')); // Uncaught Error: 出错了
// 相当于将 let result = yield x + y
// 替换成 let result = throw(new Error('出错了'));
```
`return()`是将`yield`表达式替换成一个`return`语句。
```javascript
gen.return(2); // Object {value: 2, done: true}
// 相当于将 let result = yield x + y
// 替换成 let result = return 2;
```
## yield* 表达式
如果在 Generator 函数内部,调用另一个 Generator 函数,默认情况下是没有效果的。