mirror of
https://github.com/ruanyf/es6tutorial.git
synced 2025-05-24 18:32:22 +00:00
修改generator
This commit is contained in:
parent
9d3cc774bc
commit
4bba9a0a71
@ -122,6 +122,29 @@ g.next(true) // { value: 0, done: false }
|
||||
|
||||
上面代码先定义了一个可以无限运行的Generator函数f,如果next方法没有参数,每次运行到yield语句,变量reset的值总是undefined。当next方法带一个参数true时,当前的变量reset就被重置为这个参数(即true),因此i会等于-1,下一轮循环就会从-1开始递增。
|
||||
|
||||
再看一个例子。
|
||||
|
||||
```javascript
|
||||
|
||||
function* foo(x) {
|
||||
var y = 2 * (yield (x + 1));
|
||||
var z = yield (y / 3);
|
||||
return (x + y + z);
|
||||
}
|
||||
|
||||
var it = foo(5);
|
||||
|
||||
it.next()
|
||||
// { value:6, done:false }
|
||||
it.next(12)
|
||||
// { value:8, done:false }
|
||||
it.next(13)
|
||||
// { value:42, done:true }
|
||||
|
||||
```
|
||||
|
||||
上面代码第一次调用next方法时,返回`x+1`的值6;第二次调用next方法,将上一次yield语句的值设为12,因此y等于24,返回`y / 3`的值8;第三次调用next方法,将上一次yield语句的值设为13,因此z等于13,这时x等于5,y等于24,所以return语句的值等于42。
|
||||
|
||||
注意,由于next方法的参数表示上一个yield语句的返回值,所以第一次使用next方法时,不能带有参数。V8引擎直接忽略第一次使用next方法时的参数,只有从第二次使用next方法开始,参数才是有效的。
|
||||
|
||||
## 异步操作的应用
|
||||
@ -146,6 +169,29 @@ loader.next()
|
||||
|
||||
上面代码表示,第一次调用loadUI函数时,该函数不会执行,仅返回一个遍历器。下一次对该遍历器调用next方法,则会显示Loading界面,并且异步加载数据。等到数据加载完成,再一次使用next方法,则会隐藏Loading界面。可以看到,这种写法的好处是所有Loading界面的逻辑,都被封装在一个函数,按部就班非常清晰。
|
||||
|
||||
Ajax是典型的异步操作,通过Generator函数部署Ajax操作,可以用同步的方式表达。
|
||||
|
||||
```javascript
|
||||
|
||||
function* main() {
|
||||
var result = yield request("http://some.url");
|
||||
var resp = JSON.parse(result);
|
||||
console.log(resp.value);
|
||||
}
|
||||
|
||||
function request(url) {
|
||||
makeAjaxCall(url, function(response){
|
||||
it.next(response);
|
||||
});
|
||||
}
|
||||
|
||||
var it = main();
|
||||
it.next();
|
||||
|
||||
```
|
||||
|
||||
上面代码的main函数,就是通过Ajax操作获取数据。可以看到,除了多了一个yield,它几乎与同步操作的写法完全一样。注意,makeAjaxCall函数中的next方法,必须加上response参数,因为yield语句构成的表达式,本身是没有值的,总是等于undefined。
|
||||
|
||||
下面是另一个例子,通过Generator函数逐行读取文本文件。
|
||||
|
||||
```javascript
|
||||
@ -218,6 +264,26 @@ function* f(){
|
||||
|
||||
for...of循环可以自动遍历Generator函数,且此时不再需要调用next方法。
|
||||
|
||||
```javascript
|
||||
|
||||
function *foo() {
|
||||
yield 1;
|
||||
yield 2;
|
||||
yield 3;
|
||||
yield 4;
|
||||
yield 5;
|
||||
return 6;
|
||||
}
|
||||
|
||||
for (var v of foo()) {
|
||||
console.log(v);
|
||||
}
|
||||
// 1 2 3 4 5
|
||||
|
||||
```
|
||||
|
||||
上面代码使用for...of循环,依次显示5个yield语句的值。这里需要注意,一旦next方法的返回对象的done属性为true,for...of循环就会中止,且不包含该返回对象,所以上面代码的return语句返回的6,不包括在for...of循环之中。
|
||||
|
||||
下面是一个利用generator函数和for...of循环,实现斐波那契数列的例子。
|
||||
|
||||
```javascript
|
||||
|
@ -40,6 +40,7 @@
|
||||
- Marc Harter, [Generators in Node.js: Common Misconceptions and Three Good Use Cases](http://strongloop.com/strongblog/how-to-generators-node-js-yield-use-cases/): 讨论Generator函数的作用
|
||||
- Axel Rauschmayer, [Iterators and generators in ECMAScript 6](http://www.2ality.com/2013/06/iterators-generators.html): 探讨Iterator和Generator的设计目的
|
||||
- StackOverflow, [ES6 yield : what happens to the arguments of the first call next()?](http://stackoverflow.com/questions/20977379/es6-yield-what-happens-to-the-arguments-of-the-first-call-next): 第一次使用next方法时不能带有参数
|
||||
- Kyle Simpson, [ES6 Generators: Complete Series]: 由浅入深探讨Generator的系列文章,共四篇
|
||||
|
||||
## Promise对象
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user