首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

详解 ECMAScript 6 中的生成器(4)生成器的使用案例

详解 ECMAScript 6 中的生成器(4)生成器的使用案例

生成器的使用案例在介绍完生成器的高级用法之后,下面介绍生成器在框架和实际开发中的具体案例。
生成器在框架中的使用下面通过一个例子来说明生成器在框架和第三方库中的使用。Babel 是一个流行的 JavaScript 编译工具,可以把使用了最新规范的 JavaScript        代码转换成可以在今天的平台上运行的代码。async/await 是一个实用的新特性。为了在老的平台上支持这一特性,Babel 提供了一个插件来把使用了 async/await        的代码转换成使用生成器。代码清单 18 中给出了一个使用 async/await 的简单函数。
清单 18. 使用 async/await        的代码
1
2
3
async function foo() {
  await bar();
}




上述代码经过 Babel 转换之后的结果如代码清单 19 所示。首先,async 函数被转换成生成器函数,而 await 被转换成 yield        表达式。接着通过函数_asyncToGenerator 把生成器函数转换成一个返回 Promise 的普通函数。
清单 19. 转换之后的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let foo = (() => {
  var _ref = _asyncToGenerator(function* () {
    yield bar();
  });

  return function foo() {
    return _ref.apply(this, arguments);
  };
})();

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments);
return new Promise(function (resolve, reject) { function step(key, arg) { try { var info =
gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if
(info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value)
{ step("next", value); }, function (err) { step("throw", err); }); } } return
step("next"); }); }; }




生成器在实际开发中的使用在实际开发中,生成器的一个常见使用场景是动态生成序列。代码清单 20 中的生成器函数 numbers 使用了复杂的逻辑来定义所产生的值。要理解为什么会产生这些值,关键在于理解到每次        next 方法调用会使得生成器对象运行到下一个 yield 表达式:
  • 当 i 的值是 0 到 4 时,满足条件 i<5,所以会由 yield i 来生成;
  • 当 i 变为 5 之后,没有任何条件满足,不产生任何值;
  • 当 i 为 6 时,满足第二个条件,因此产生值 12;
  • 当 i 为 7 时,满足最后一个条件,产生值 49;
  • 当 i 为 8 时,满足第二个条件,产生值 16;
  • 当 i 为 9 时,满足第三个条件,产生值 27;
  • 直到 i 为 12,才由第三个条件产生值 36;
  • 最后在当 i 为 14 时,产生值 98。
清单 20.        使用生成器来产生序列
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function *numbers() {
  for (let i = 0; i < 20; i++) {
    if (i < 5) {
      yield i;
    } else if (i < 10 && i % 2 === 0) {
      yield i * 2;
    } else if (i < 15 && i % 3 === 0) {
      yield i * 3;
    } else if (i % 7 === 0) {
      yield i * 7;
    }
  }
}

debug(numbers());
// -> 输出数字: 0, 1, 2, 3, 4, 12, 49, 16, 27, 36, 98




小结ECMAScript 6 中的生成器是一个强大的工具。目前在很多 JavaScript 框架和库中都得到了应用。本文对生成器的基本概念、基本用法、return 和 throw        方法、以及 yield * 表达式的用法都做了详细的介绍。通过本文的介绍,读者可以对生成器有一个更深入的了解,并尝试在实际开发中使用生成器来解决一些具体的问题。
返回列表