js之generator

基本使用

Generator 函数是 ES6 提供的一种异步编程解决方案.生成器函数在执行时能暂停,后面又能从暂停处继续执行。

Generator 函数function关键字与函数名之间有一个星号;函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)
function* name([param[, param[, ... param]]]) { statements }

调用一个生成器函数并不会马上执行它里面的语句,而是返回一个这个生成器的 迭代器 ( iterator )对象。
当这个迭代器的 next() 方法被首次(后续)调用时,其内的语句会执行到第一个(后续)出现yield的位置为止,yield 后紧跟迭代器要返回的值。
或者如果用的是 yield*(多了个星号),则表示将执行权移交给另一个生成器函数(当前生成器暂停执行)。
next()方法返回一个对象,这个对象包含两个属性:value 和 done,value 属性表示本次 yield 表达式的返回值,done 属性为布尔类型,表示生成器后续是否还有 yield 语句,即生成器函数是否已经执行完毕并返回。

function * gen () {
  let val
  val = yield 1
  console.log(`1:${val}`)
  val = yield 2
  console.log(`2:${val}`)
  val = yield 3
  console.log(`3:${val}`)
}

var g = gen()

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

yield传参

调用 next()方法时,如果传入了参数,那么这个参数会传给上一条执行的 yield语句左边的变量,例如下面例子中的 x :

function *gen(){
    yield 10;
    x=yield 'foo';
    yield x;
}

var gen_obj=gen();
console.log(gen_obj.next());// 执行 yield 10,返回 10
console.log(gen_obj.next());// 执行 yield 'foo',返回 'foo'
console.log(gen_obj.next(100));// 将 100 赋给上一条 yield 'foo' 的左值,即执行 x=100,返回 100
console.log(gen_obj.next());// 执行完毕,value 为 undefined,done 为 true

Generator 对象的方法:next、return、throw。

Generator.prototype.next()
// 返回一个由 yield表达式生成的值。

Generator.prototype.return()
// 返回给定的值并结束生成器。

Generator.prototype.throw()
// 向生成器抛出一个错误。

其中,next()方法见上,不多赘述。下面简要看下return和throw。

// return() 
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 }

// 如果对已经处于“完成”状态的生成器调用return(value),则生成器将保持在“完成”状态。
// 如果没有提供参数,则返回对象的value属性与示例最后的.next()方法相同。
// 如果提供了参数,则参数将被设置为返回对象的value属性的值。
// throw()
function* gen() {
  while(true) {
    try {
       yield 42;
    } catch(e) {
      console.log("Error caught!");
    }
  }
}

var g = gen();
g.next(); // { value: 42, done: false }
// 使用 throw方法向该生成器抛出一个异常,该异常通常可以通过 try...catch 块进行捕获.
g.throw(new Error("Something went wrong")); // "Error caught!"

生成器函数不能当构造器使用

function* f() {}
var obj = new f; // throws "TypeError: f is not a constructor"

应用场景举例

抽奖:每次返回单次执行的结果

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值