前端JavaScript基础训练系列二百零三:regenerator 来转换前面的生成器

本文介绍了如何将ES6生成器转换为前ES6兼容的代码,使用regeneratorRuntime库自动化这个过程。生成器在处理异步流程时提供了更清晰的解决方案,避免了回调地狱。
摘要由CSDN通过智能技术生成

(1) 对迭代器的 next() 的第一个调用会把生成器从未初始化状态转移到状态 1,然后调用 process() 来处理这个状态。request(…) 的返回值是对应 Ajax 响应的 promise,作为 value 属性从 next() 调用返回。
(2) 如果 Ajax 请求成功,第二个 next(…) 调用应该发送 Ajax 响应值进来,这会把状态转 移到状态 2。再次调用 process(…)(这次包括传入的 Ajax 响应值),从 next(…) 返回 的 value 属性将是 undefined。
(3) 然而,如果 Ajax 请求失败的话,就会使用错误调用 throw(…),这会把状态从 1 转移到 3(而非 2)。再次调用 process(…),这一次包含错误值。这个 case 返回 false,被作 为 throw(…) 调用返回的 value 属性。
从外部来看(也就是说,只与迭代器交互),这个普通函数 foo(…) 与生成器 *foo(…) 的 工作几乎完全一样。所以我们已经成功地把 ES6 生成器转为了前 ES6 兼容代码!
然后就可以手工实例化生成器并控制它的迭代器了,调用var it = foo(“…”)和 it.next(…) 等。甚至更好的是,我们可以把它传给前面定义的工具 run(…),就像 run(foo,“…”)。

自动转换

前面的 ES6 生成器到前 ES6 等价代码的手工推导练习,向我们教授了概念上生成器是如何 工作的。但是,这个变换非常复杂,并且对于代码中的其他生成器而言也是不可移植的。 这部分工作通过手工实现十分不实际,会完全抵消生成器的一切优势。
但幸运的是,已经有一些工具可以自动把 ES6 生成器转化为我们推导出来的 结果那样的代码。它们不仅会为我们完成这些笨重的工作,还会处理我们忽略的几个枝节 问题。

如果使用 regenerator 来转换前面的生成器的话,以下是产生的代码(本书写作之时): ```js
// request(…)是一个支持Promise的Ajax工具
var foo = regeneratorRuntime.mark(function foo(url) {
var val;
return regeneratorRuntime.wrap(function foo$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
context$1$0.prev = 0;
console.log( “requesting:”, url );
context$1$0.next = 4;
return request( url );
case 4:
val = context$1$0.sent;
console.log( val );
context$1$0.next = 12;
break;
case 8:
context$1$0.prev = 8;
context$1$0.t0 = context$1$0.catch(0);
console.log(“Oops:”, context$1$0.t0);
return context$1$0.abrupt(“return”, false);
case 12:
case “end”:
return context$1$0.stop();
}
}, foo, this, [[0, 8]]);
});


这与我们手工推导的结果有一些明显的相似之处,比如那些 switch/case 语句,而且我们 甚至看到了移出闭包的 val,就像我们做的一样。
当然,一个不同之处是,regenerator 的变换需要一个辅助库 regeneratorRuntime,其中包 含了管理通用生成器和迭代器的所有可复用逻辑。这些重复代码中有很多和我们的版本不 同,但即使这样,很多概念还是可以看到的,比如context$1$0.next = 记录生成器的下 一个状态。
主要的收获是,生成器不再局限于只能在 ES6+ 环境中使用。一旦理解了这些概念,就可 以在代码中使用,然后使用工具将其变换为与旧环境兼容的代码。
这比仅仅将修改后的 Promise API 用作前 ES6 Promise 所做的工作要多得多,但是,付出的 代价是值得的,因为在实现以合理的、明智的、看似同步的、顺序的方式表达异步流程方 面,生成器的优势太多了。
一旦迷上了生成器,就再也不会想回到那一团乱麻的异步回调地狱中了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值