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:
parent
ba08efe8d1
commit
4dbd9b0f48
@ -265,6 +265,27 @@ b.next(13) // { value:42, done:true }
|
|||||||
|
|
||||||
注意,由于`next`方法的参数表示上一个`yield`表达式的返回值,所以在第一次使用`next`方法时,传递参数是无效的。V8 引擎直接忽略第一次使用`next`方法时的参数,只有从第二次使用`next`方法开始,参数才是有效的。从语义上讲,第一个`next`方法用来启动遍历器对象,所以不用带有参数。
|
注意,由于`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 函数外面再包一层。
|
如果想要第一次调用`next`方法时,就能够输入值,可以在 Generator 函数外面再包一层。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@ -287,27 +308,6 @@ wrapped().next('hello!')
|
|||||||
|
|
||||||
上面代码中,Generator 函数如果不用`wrapper`先包一层,是无法第一次调用`next`方法,就输入参数的。
|
上面代码中,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 循环
|
||||||
|
|
||||||
`for...of`循环可以自动遍历 Generator 函数时生成的`Iterator`对象,且此时不再需要调用`next`方法。
|
`for...of`循环可以自动遍历 Generator 函数时生成的`Iterator`对象,且此时不再需要调用`next`方法。
|
||||||
@ -599,7 +599,7 @@ try {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
上面代码中,第二个`next`方法向函数体内传入一个参数42,数值是没有`toUpperCase`方法的,所以会抛出一个TypeError错误,被函数体外的`catch`捕获。
|
上面代码中,第二个`next`方法向函数体内传入一个参数42,数值是没有`toUpperCase`方法的,所以会抛出一个 TypeError 错误,被函数体外的`catch`捕获。
|
||||||
|
|
||||||
一旦 Generator 执行过程中抛出错误,且没有被内部捕获,就不会再执行下去了。如果此后还调用`next`方法,将返回一个`value`属性等于`undefined`、`done`属性等于`true`的对象,即 JavaScript 引擎认为这个 Generator 已经运行结束了。
|
一旦 Generator 执行过程中抛出错误,且没有被内部捕获,就不会再执行下去了。如果此后还调用`next`方法,将返回一个`value`属性等于`undefined`、`done`属性等于`true`的对象,即 JavaScript 引擎认为这个 Generator 已经运行结束了。
|
||||||
|
|
||||||
@ -649,7 +649,7 @@ log(g());
|
|||||||
|
|
||||||
## Generator.prototype.return()
|
## Generator.prototype.return()
|
||||||
|
|
||||||
Generator函数返回的遍历器对象,还有一个`return`方法,可以返回给定的值,并且终结遍历Generator函数。
|
Generator 函数返回的遍历器对象,还有一个`return`方法,可以返回给定的值,并且终结遍历 Generator 函数。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
function* gen() {
|
function* gen() {
|
||||||
@ -706,6 +706,44 @@ g.next() // { value: 7, done: true }
|
|||||||
|
|
||||||
上面代码中,调用`return`方法后,就开始执行`finally`代码块,然后等到`finally`代码块执行完,再执行`return`方法。
|
上面代码中,调用`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* 表达式
|
## yield* 表达式
|
||||||
|
|
||||||
如果在 Generator 函数内部,调用另一个 Generator 函数,默认情况下是没有效果的。
|
如果在 Generator 函数内部,调用另一个 Generator 函数,默认情况下是没有效果的。
|
||||||
|
Loading…
x
Reference in New Issue
Block a user