前端JavaScript基础训练系列一百八十七:生成器 +Promise

在前面的讨论中,我们展示了如何异步迭代生成器,这是一团乱麻似的回调在顺序性和合 理性方面的巨大进步。但我们错失了很重要的两点:Promise 的可信任性和可组合性()!
别担心,我们还会重获这些。ES6 中最完美的世界就是生成器(看似同步的异步代码)和 Promise(可信任可组合)的结合。
但如何实现呢?
里在运行 Ajax 例子中基于 Promise 的实现方法:

    function foo(x,y) {
         return request(
             "http://some.url.1/?x=" + x + "&y=" + y
         );
}
     foo( 11, 31 )
     .then(
         function(text){
             console.log( text );
         },
         function(err){
             console.error( err );
         }
);

在前面的运行 Ajax 例子的生成器代码中,foo(…) 没有返回值(undefined),并且我们的
迭代器控制代码并不关心 yield 出来的值。

而这里支持 Promise 的 foo(…) 在发出 Ajax 调用之后返回了一个 promise。这暗示我们可 以通过 foo(…) 构造一个 promise,然后通过生成器把它 yield 出来,然后迭代器控制代码 就可以接收到这个 promise 了。
但迭代器应该对这个 promise 做些什么呢?

它应该侦听这个 promise 的决议(完成或拒绝),然后要么使用完成消息恢复生成器运行,
要么向生成器抛出一个带有拒绝原因的错误。 我再重复一遍,因为这一点非常重要。获得 Promise 和生成器最大效用的最自然的方法就

是 yield 出来一个 Promise,然后通过这个 Promise 来控制生成器的迭代器。

让我们来试一下!首先,把支持 Promise 的 foo(…) 和生成器 *main() 放在一起:

function foo(x,y) {
         return request(
             "http://some.url.1/?x=" + x + "&y=" + y
         );
}
     function *main() {
         try {
             var text = yield foo( 11, 31 );
             console.log( text );
         }
         catch (err) {
             console.error( err );
} }

这次重构代码中最有力的发现是,*main() 之中的代码完全不需要改变!在生成器内部, 不管什么值 yield 出来,都只是一个透明的实现细节,所以我们甚至没有意识到其发生, 也不需要关心。

但现在如何运行 *main() 呢?还有一些实现细节需要补充,来实现接收和连接 yield 出来 的 promise,使它能够在决议之后恢复生成器。先从手工实现开始:

var it = main();
     var p = it.next().value;
// 等待promise p决议 p.then(
         function(text){
             it.next( text );
},
         function(err){
             it.throw( err );
} );

实际上,这并没有那么令人痛苦,对吧?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值