ES6 学习Generator 语法

Generator “生成器” 简介

Generator 函数是一个函数

但是有两个特征。function关键字后面有一个星号;函数体内部用到yield表达式。

function* myGenerator(){
  yield 'hi';
  yield 'girl';
  return 'I Love You';
}
let boy = myGenerator();

boy.next() // { value: 'hi', done: false }
boy.next() // { value: 'girl', done: false }
boy.next() // { value: 'I Love You', done: true }
boy.next() // { value: undefined, done: true }
// 该函数有三种状态 'hi' 'girl' 和结束 'I Love You'

yield “产出” 表达式

就是Genertor 内部用来暂停的关键词,yield表达式也只能使用在 Generator 函数中。
Genertor函数的运行逻辑:

(1)当遇到yield表达式,就会暂停执行后续代码,将紧跟在yield后面的表达式结果,作为返回对象中的value属性值。

(2)再一次调用next方法,会继续向下执行,直到再次遇到yield表达式。

(3)没有新的yield表达式时,会运行到函数有return语句为止,将return后面的表达式结果,作为返回对象中的value属性值。

(4)当该函数没return语句时,则返回的对象的value属性值为undefined

next 方法

yield表达式本身总是返回undefined
next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。

function* fn(x){
  let a = 3 * (yield (x + 2));
  let b = yield (a * 2);
  return (a + b);
}
let fn1 = fn(2),fn2 = fn(2);
fn1.next() // {value:4, done:false}
fn1.next() // {value:NaN, done:false}
fn1.next() // {value:NaN, done:true}
fn2.next() // {value:4, done:false}
fn2.next(3) // {value:18, done:false}
fn2.next(6) // {value:15, done:true}
// 注意,由于`next`方法的参数表示上一个`yield`表达式的返回值,所以在第一次使用`next`方法时,传递参数是无效的。

for…of 循环遍历

for...of循环会自动遍历 Generator 函数,不需要调用next()方法

function* circle(){
  yield 1;
  yield 2;
  yield 3;
  yield 4;
  return 'end';
}
for(let el of circle()){
  console.log(el);
}
// 1 2 3 4 注意当next方法中返回对象done属性为true,该条对象将不会被返回。

斐波拉契数列

Generator实现斐波拉契数列

function* fibonacci() {
  let [a, b] = [0, 1];
  for (;;) {
    yield b;
    [a, b] = [b, a + b];
  }
}

for (let n of fibonacci()) {
  if (n > 1000) break;
  console.log(n);
}

实例对象

实现对象具备Iterator接口

function* objectEntries(){
  let keys = Object.keys(this);
  for (let key of keys){
    yield [key,this[key]];
  }
}
let person = {
  name: 'shaoin',
  age: 88
}
person[Symbol.iterator] = objectEntries;

for(let [key, value] of person){
  console.log(key + ":" + value);
}
// name:shaoin age:88

for...of循环以外,

function acount(){
  yield 1;
  yield 2;
  return 4;
}

还有:

扩展运算符(...

[...acount()]  // [1, 2]

Array.from 方法

Array.from(acount()) // [1, 2]

解构赋值

let [x, y] = numbers(); // x = 1, y= 2
Generator.prototype.throw() 抛出错误

throw方法可以接受一个参数,该参数会被catch语句接收

function* fn(){
  try{
    yield;
  }catch(e){
    console.log(e);
  }
};
let o = fn();
o.throw(new Error('出错了')) // Error: 出错了
Generator.prototype.return() 终止函数

return()方法,返回给定的值,并终结Generator函数

function* fn(){
  yield 1;
  yield 2;
}
let o = fn();
o.next() // {value: 1, done: false}
o.return('some') // {value: "some", done: true}
o.next() // {value: undefined, done: true}
next、throw、return 的共同点和差别

它们的作用都可以让Generator函数继续执行

  1. next()是将yield表达式替换成一个已计算的结果或表达式;
  2. throw()是将yield表达式替换成一个throw需要执行抛出错误的语句;
  3. return()是将yield表达式替换成一个return需要终止和返回值的语句
yield* 表达式使用

yield*表达式用来在Generator函数里有效执行另一个Generator函数。

function* fn1(){
  yield 1;
  yield 2;
}

function* fn2(){
  yield 1;
  yield 2;
  yield 3;
  yield 4;
}

// 相当于
function* fn2(){
  yield* fn1();
  yield 3;
  yield 4;
}

// 相当于
function* fn2(){
  for(let e of fn1()){
    yield e;
  }
  yield 3;
  yield 4;
}
for (let e of fn2()){
  console.log(e)
}
// 1 2 3 4

yield* 后面可以跟一个字符串或者跟一个数组

function* fn(){
  yield 'hi';
  yield* 'shaoin'
}
let o = fn();
o.next() // {value: 'hi', done: false}
o.next() // {value: 's', done: false}

Generator函数作为对象属性时,可以简写

let obj = {
  * fn(){
    ...
  }
};
// 相当于
let obj = {
	fn:function* (){
    ...
  }
}
协程

“协程”(coroutine),意思是多个线程互相协作,完成异步任务。

协程有点像函数,又有点像线程:

  • 第一步,协程C1开始执行;
  • 第二步,协程C1执行到一半,进入暂停,执行权转移到协程C2;
  • 第三步,(一段时间后)协程C2将执行权交还C1;
  • 第四步,协程C1恢复执行。
function* fn(x){
  let val = yield x * 2;
  return val;
}
var g = fn(2);
o.next() //  { value: 4, done: false }
o.next(3) //  { value: 3, done: true }

参考文献

阮一峰老师的 ECMAScript 6 入门


求点赞 求评论 求收藏 ~~ 今天的学习记录暂时到这... ~~ 求点赞 评论 求收藏
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shaoin_2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值