generator函数学习笔记

一、基本概念

Generator函数是一种可以暂停执行,返回iterator对象的函数,yield是暂停标识

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

Generator函数在function后面有一个*,内部有yield语句

function* gen(){
    yield 1;
    yield 2;
    return '1'
}

let g = gen(); //调用Generator函数返回遍历器对象
console.log(g.next())//{"value":1,"done":false} 
console.log(g.next())//{"value":2,"done":false}

console.log(g.next())//{"value":"1","done":true}
 console.log(g.next())//{"value":undefined,"done":true}

如果内部没有yield命令,generator函数和普通函数没有差别,只是暂停执行。

二、for of

generator函数返回遍历器对象,可以用for of遍历

function* gen(){
    yield 1;
    yield 2;
    return '1'
}

for(let i of gen()){
  console.log(i)
}
//1
//2

三、next return throw

iterator对象都有这三个方法,但一般的内置默认的Symbol.iterator返回的对象没有return throw方法。

1.next方法可以向generator函数内部传递数据  yield命令本身没有返回值,next方法的参数可以用作yield的赋值。

function* gen(){
    yield 1;
    let a = yield 2;
    console.log(a) //10
    return a
}
let g = gen();
console.log(g.next())//{"value":1,"done":false}
console.log(g.next()) //{"value":2,"done":false} 10
console.log(g.next(10)) //{"value":10,"done":false}

2.Generator函数返回的遍历器对象值,还有一个return方法,可以返回给定的值,并且终结遍历Generator函数。

function* gen() {
  yield 1;
  yield 2;
  yield 3;
}
var g = gen();
g.next()        // { value: 1, done: false }
g.return("foo") // { value: "foo", done: true } 遍历结束
g.next()        // { value: undefined, done: true }

3.Generator函数返回的遍历器对象,都有一个throw方法,

a.可以在函数体外抛出错误,然后在Generator函数体内捕获。

b.内部抛出错误,而内部没有try catch捕获,外部可以捕获

c.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函数体内的catch语句捕获,此时Generator函数就算执行完成了,不会再继续执行了。遍历器对象i第二次抛出错误,由于Generator函数内部的catch语句已经执行过了,不会再捕捉到这个错误了,所以这个错误就被抛出了Generator函数体,被函数体外的catch语句捕获。

要注意遍历器对象的throw与全局的throw的区别 后者只能被函数体外的catch捕获。

四、yield*

yield* 后面是遍历器对象  可用于在generator函数内调用另一个generator函数 yield*相当于运用了for of

五、generator用于异步的同步表示

因为generator函数是可以暂停的,且yield是同步的,所有后一个yield肯定在上一个结束后才运行。

六、generator与协程

协城:可以交换执行权,达到“伪并行”的状态,其实在同一时间还是只有一个函数在运行

Generator函数是ECMAScript 6对协程的实现,但属于不完全实现。Generator函数被称为“半协程”(semi-coroutine),意思是只有Generator函数的调用者,才能将程序的执行权还给Generator函数。如果是完全执行的协程,任何函数都可以让暂停的协程继续执行。

七、generator的this

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

function* g() {
  this.a = 11;
}

let obj = g();
obj.a // undefined

 

Generator函数返回的总是遍历器对象,而不是this对象。所有obj拿不到a属性

posted on 2015-12-16 20:40  xinup  阅读(603)  评论(0编辑  收藏  举报

导航