Generator

Generator 函数是 ES6 提供的一种异步编程解决方案
Generator 函数看是跟普通函数一样,但是有两个特征:
1. function 与 函数名之间有 一个 “*”(星号)
2. 函数内部使用 yield 语句

function* Ge(){
    console.log('setp1');
    yield 'setp1 over';
    console.log('step2');
    yield 'step2 over';
    console.log('step3');
    return 'end'
}
 var s=Ge()
s.next()
//setp1
//{ value: 'setp1 over', done: false }
s.next()
//step2
//{ value: 'step2 over', done: false }
s.next()
//step3
//{ value: 'end', done: true }

调用遍历器对象的next方法,使得指针移向下一个状态
即每次调用使用 next方法
可以理解为遇到yield是暂停,next继续执行
每次next 都会返回一个{value:”,done:”}的对象想

使用注意:
* yield语句如果用在一个表达式之中,必须放在圆括号里面
* yield 作为函数的参数可以不加括号

与 Iterator 接口的关系

Generator函数就是遍历器生成函数
给对象赋值 Symbol.iterator属性 ,该对象具有 Interator 接口

var obj[Symbol.iterator] = function* (){
    yield 1;
    yield '2';
    yield true;
};
//[Function]
[...obj]
//[ 1, '2', true ]

next 方法的参数

yield 句本身没有返回值,或者返回值为 undefined
next 可以带一个参数 ,该参数会被当做上一yield 的返回值

function* f() {
   for(var i = 0; true; i++) {
     var reset = yield i;
     console.log('i=='+i);
     console.log('reset=='+reset);
     if(reset) { i = -1; }
   }
 }

var r = f()
r.next()
//{ value: 0, done: false }

 r.next()
//i==0
//reset==undefined
//{ value: 1, done: false }

r.next(true)
//i==1
//reset==true
//{ value: 0, done: false }

Generator.prototype.throw()

Generator函数返回的遍历器对象,都有一个throw方法,可以在函数体外抛出错误,然后在Generator函数体内捕获。

var g = function* () {
  try {
    yield;
  } catch (e) {
    console.log('内部捕获', e);
  }
};

var i = g();
i.next();

try {
  i.throw('a');
  i.throw('b');
} catch (e) {
  console.log('外部捕获', e);
}

//内部捕获 a
//外部捕获 b

一旦Generator执行过程中抛出错误,且没有被内部捕获,就不会再执行下去了

Generator.prototype.return()

Generator函数,return方法可以返回给定的值,并终结遍历Generator函数
调用 Generator 的return 方法后 返回值就return的参数 “done”的值“true”;终结Generator函数,再调用next 是 “value”为“undefined”
return 可以重设 “value”值

 g.next()
//{ value: 1, done: false }
 g.return('ok')
//{ value: 'ok', done: true }
 g.next()
//{ value: undefined, done: true }
 g.return('no')
//{ value: 'no', done: true }

需要注意的是 如果Generator函数内部有try…finally代码块,那么return方法会推迟到finally

function* ge() {
    try{
        yield '1';
        yield '2';
        yield '3';
    }finally{
        yield '4'
        yield '5'
    }

}

var g = ge();
g.next()
//{ value: '1', done: false }
g.return('foo')
//{ value: '4', done: false }
g.next()
//{ value: '5', done: false }

yield*

默认条件下在Generator 函数内部 调用另一个Generator 函数 是无效的

function* a(){
    yield 'a1';
    yield 'a2';
    b();
    yield 'a3';
}
function* b(){
    yield 'b1';
    yield 'b2';
    yield 'b3';
}
g.next()
//{ value: 'a1', done: false }
g.next()
//{ value: 'a2', done: false }
g.next()
//{ value: 'a3', done: false }
g.next()
//{ value: undefined, done: true }

///

function* a(){
    yield 'a1';
    yield 'a2';
    yield* b();
    yield 'a3';
}
function* b(){
    yield 'b1';
    yield 'b2';
    yield 'b3';
}
var g=a();
g.next()
//{ value: 'a1', done: false }
g.next()
//{ value: 'a2', done: false }
g.next()
//{ value: 'b1', done: false }
g.next()
//{ value: 'b2', done: false }
g.next()
//{ value: 'b3', done: false }
g.next()
//{ value: 'a3', done: false }
g.next()
//{ value: undefined, done: true }


yield* 后面一个数组,或支持遍历器的数据结构 都可以对其遍历

Generator函数的this

Generator函数总是返回一个遍历器,ES6规定这个遍历器是Generator函数的实例,也继承了Generator函数的prototype对象上的方法
Generator 的实例的this 返回的 总是遍历对象
解决方案

function* ge(){
    this.a='a';
    this.b=function (){
        console.log('b')
    };
    yield '1';
    yield '2';
    yield '3';

}
function Ge(){
    return GeneratorFn.call(GeneratorFn.prototype)
}
var g = new Ge()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值