ES6新特性 Generator函数和yield

intro

ES6引入了Generator函数,可以通过yield关键字,把函数的执行流挂起,
这为改变执行流程提供了可能,从而为异步编程提供解决方案。

API

function* foo() {...}; // 定义生成器函数generator function
f = foo() 获取Generator对象,fooGenerator函数。

g.next(?v) 程序向后执行,返回下一个由yield表达式生成的值。(对象格式:{value: xxx, done: false})。
直到得到包含return值的对象{value: 返回值, done: true}。或遇到异常。Uncaught xxx
next()操作到return语句或抛出异常语句会被终止。
参数v可以设置上一条yield语句的返回值。
yield语句的返回值默认值undefined
g.return(?v)直接结束生成器。返回对象{value: v, done: true}。参数v不传则为undefined
g.throw(?e) 向生成器抛出一个错误。

刚定义f和每次调用f.next()后,f状态为foo {<suspend>}
生成器终止后,状态为foo {<closed>}

demo

  • next()基本用法

    function* foo() {
      console.log(1);
      yield 2;
      console.log(3);
      yield 4;
      console.log(5);
      return 6;
      console.log(7);
      yield 8;
    }
    
    f = foo();
    Object.prototype.toString.apply(f)  // "[object Generator]"
    
    f.next();
    // 1
    // {value: 2, done: false}
    f.next();
    // 3
    // {value: 4, done: false}
    f.next(); // 这次会遇到return语句。生成器终止。
    // 5
    // {value: 6, done: true}
    f.next(); // 这次不会打印7。函数已经return过,不会执行之后的语句。返回的对象也没有value。
    // {value: undefined, done: true}
    
  • next(?value)的参数

    function* foo() {
      var one = yield 1;
      var two = yield 2;
      var three = yield 3;
      console.log(one, two, three);
      return 666;
    }
    f = foo();
    
    f.next();   // 执行到第一个yield语句。
    // {value: 1, done: false}
    f.next(12); // 执行到第2个yield语句,并设置第1个yield表达式的返回值one为指定值。
    // {value: 2, done: false}
    f.next();   // 执行到第3个yield,并设置two为undefined。
    // {value: 3, done: false}
    f.next(56);   // 这次是返回值。并设置three为56。
    // 12 undefined 56
    // {value: 666, done: false}
    
  • return(?value)的参数
    f.return()会直接终止生成器,返回的对象为{value: undefined, done: true}
    f.return(v)不同的是,返回的对象的value属性为指定值v,即{value: v, done: true}

yieldyield*

  • yield关键字用于暂停和恢复一个生成器函数generator function(function*或遗留的生成器函数)。
    [rv] = yield [expression];
  • yield*表达式用于委托给另一个generator|可迭代对象。
    yield* [[expression]];
function* foo() {
  yield 1;
  yield 2;
  return 333;
}
function* bar() {
  yield* [1, 2]
  return 333;
}

f = foo();
b = bar();
// 之后f和b的使用相同。

yield*表达式表示yield返回一个遍历器对象,用于在generator function内部,调用另一个generator function

应用

  • 实现Iterator,(用for..of)遍历对象。
    function* objEntries(obj) {
      let keys = Reflect.ownKeys(obj);
      for (let key of keys) {
        yield [key, obj[key]];
      }
    }
    var boy = {name: "JT", age: 20};
    
    var entries = objEntries(boy);
    for (let e of entries) {
      console.log(e);
    }
    // (2) ["name", "JT"]
    // (2) ["age", 20]
    
    var entries = objEntries(boy);
    for (let [prop, value] of entries) {
      console.log(`${prop} = ${value}`);
    }
    // name = JT
    // age = 20
    

object不具备Iterator接口,无法用for..of遍历。
不过可以用generator function加上Iterator接口,然后可以用for..of遍历。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值