2017/06/06
学习redux-saga
过程中,发现它使用到了Generator
函数,把这个仔细读了一遍。
Generator
函数是ES 6
提供的一种异步编程解决方案,语法与传统的函数完全不同。
学习过程中,整理一些基础的注意点,具体的语法和API不在这里详细解释。
定义
function* helloWorld(){
yield 'hello';
yield ' world';
return 'ending';
}
注意点
定义
ES 6
没有确定*
的位置,所有你可以这样写:
function* f();
function *f();
function * f();
function*f();
建议第一种
一般使用
let hw = helloWorld();
hw.next(); // {value: 'hello', done: false}
hw.next(); // {value: ' world', done:: false}
hw.next(); // {value: 'ending', done: true}
- 调用构造函数,返回的是一个
Iterator Object
(遍历器对象) - 调用遍历器对象的
next
方法,返回一个对象,固定两个字段:value
和done
。value
的值为函数内紧跟yiled
语句的值,done
表示遍历是否结束
yield 和 return 效果类似,不同的是 return 只能有一个,并且 return 之后的 yiled 不执行
next 方法是惰性求值
yield语句
-
yield
语句用作函数参数或赋值表达式的右边,可以不加括号 -
yield
语句只能在Generator
函数中使用 -
yiled
语句没有返回值,或者说返回值为undefined
-
可以通过给
next
方法传递参数,这个参数作为yield
语句的返回值
function* f(){
for(let i=0;;i++){
let reset = yield i; // next 没有参数时,reset 的值永远为 undefined
if(reset){
i = -1;
}
}
}
let g = f();
g.next(); // {value: 0, done: false}
g.next(); // {value: 1, done: false}
g.next(); // {value: 2, done: false}
g.next(true); // {value: 0, done: false}
因为 next 方法的参数表示上一次 yield 语句的返回值,所以只能在第二次 next 方法传递参数才是有效的
for...of
for...of
可以自动遍历Generator
函数,无需使用next
方法
function* f(){
yield 1;
yield 2;
return 3
}
for(let v of f()){
console.log(v);
}
// 1 2
// 注意,这里并不是 value 和 done 的数据格式
next 方法返回对象的 done 为 true 时,循环终止,并不包含该返回对象,所以上例不包含 return 的值
yield*语句
在Generator
函数中执行另一个Generator
函数,使用yield*
语句
网友评论