通过yield&co获得承诺的价值

Mar*_*ahn 10 javascript generator node.js ecmascript-harmony co

我试图找出如何获得承诺的价值yield,可能是"co":

function *(){
    var someVar = yield functionThatReturnsAPromise();
}
Run Code Online (Sandbox Code Playgroud)

被调用的函数不是生成器,只是普通函数.有了上面的,someVar == Promise但我想要解决的价值.是否合作或其他一些库有这样做的方法吗?

Kla*_*r_1 7

是的,co可以做到这一点.你必须在co调用中包装父函数:

co(function *(){
    var someVar = yield functionThatReturnsAPromise();
})()
Run Code Online (Sandbox Code Playgroud)

someVar里面会成为解决价值.如果承诺被拒绝,错误可以与基本try {} catch (e) {}陈述相对应.

  • 对我来说,返回`Promise {<pending>}` (2认同)

Lod*_*rds 7

通常,yield act对于其自己的暂停执行(yield函数的左侧)返回与生成器的调用函数相同的值.在这个简单的例子中,从1到5的例子计算,yield的输入是生成器函数的yield的输出以及生成器的执行路径:

function* inc() {
    var g = 0; 
    while (true) {
      g = yield g + 1;
    }
}

var incGen = inc();
for (i = incGen.next().value; i <= 5; i = incGen.next(i).value) {
  console.log(i);  //                                ^ input of generator is last output
}
Run Code Online (Sandbox Code Playgroud)

但是,调用函数也可以调用生成器,但是将最后一个yield的输出替换为另一个值,或者甚至将异常抛给生成器的执行.在promise的情况下,返回promise的函数可能会产生该promise的结果而不是promise本身.所以在这种情况下:

var someVar = yield functionThatReturnsAPromise();
     ^ output  !=   ^ input
Run Code Online (Sandbox Code Playgroud)

您希望yield作为一个函数,将promise作为输入,并将已解析的promise作为输出返回到生成器函数.

它恰好co可以为你做到这一点.您需要做的就是将您的生成器函数提供给co函数:

co(function *(){
    var someVar = yield functionThatReturnsAPromise();
})
Run Code Online (Sandbox Code Playgroud)

为了更好地理解这是如何工作的,这里是一个函数的例子,它与co做同样的事情:

function async(makeGenerator){
  return function (){
    var generator = makeGenerator.apply(this, arguments)

    function handle(result){
      if (result.done) return result.value

      return result.value.then(function (res){
        return handle(generator.next(res))  // <- sets output of yield to the promise result
      }, function (err){                    //    and returns input promise 
        return handle(generator.throw(err)) // <- throw promise exception to generator function
      })
    }

    return handle(generator.next()) // <- first time call, input of yield is a promise
  }
}
Run Code Online (Sandbox Code Playgroud)

来源于Forbes Lindesay现在着名的关于这个概念的演讲