ES6 生成器
ES6 的很多特性都跟 Generator 扯上关系,而且实际用处比较广, 包含了任何需要异步的模块, 比如 ajax, filesystem, 或者数组对象遍历等都可以用到。
一. 基本使用
Generator 函数和普通的函数区别有两个:
- function 和函数名之间有一个
*
号, - 函数体内部使用了 yield 表达式。比如这样:
function * gen() {
yield "1";
yield "2"
}
这个玩意儿如果运行的话,会返回一个 Iterator 实例, 然后再执行 Iterator 实例的next()方法, 那么这个函数才开始真正运行, 并把 yield 后面的值包装成固定对象并返回,直到运行到函数结尾, 最后再返回undefined;
function* fibonacci() {
yield 1;
yield 2;
}
var it = fibonacci();
console.log(it); // "Generator { }"
console.log(it.next()); // 1
console.log(it.next()); // 2
console.log(it.next()); //undefined
1.1 yield
Generator 函数返回的 Iterator 运行的过程中,如果碰到了 yield, 就会把 yield 后面的值返回, 此时函数相当于停止了, 下次再执行 next() 方法的时候, 函数又会从上次退出去的地方重新开始执行;
如果把yield和return一起使用的话, 那么 return 的值也会作为最后的返回值, 如果 return 语句后面还有 yield, 那么这些 yield 不生效:
function* gen() {
yield 0;
yield 1;
return 2;
yield 3;
};
let g = gen();
console.log(g.next(),g.next(),g.next(),g.next());
//输出:{ value: 0, done: false } { value: 1, done: false } { value: 2, done: true } { value: undefined, done: true }
二. next 方法传参
如果给 next 方法传参数, 那么这个参数将会作为上一次yield 语句的返回值 ,这个特性在异步处理中是非常重要的, 因为在执行异步代码以后, 有时候需要上一个异步的结果, 作为下次异步的参数, 如此循环:
function* foo(x) {
var y = 2 * (yield (x + 1));
var z = yield (y / 3);
return (x + y + z);
}
var a = foo(5);
a.next() // Object{value:6, done:false}
a.next() // Object{value:NaN, done:false}
a.next() // Object{value:NaN, done:true}
var b = foo(5);
b.next() // { value:6, done:false }
b.next(12) // { value:8, done:false }
b.next(13) // { value:42, done:true }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: ES6 迭代器
下一篇: 谈谈自己对于 AOP 的了解
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论