Getting a promise's value via yield & co

前端 未结 2 1441
隐瞒了意图╮
隐瞒了意图╮ 2020-12-17 18:25

I\'m trying to figure out how to get the value of a promise via yield, possibly with \"co\":

function *(){
    var someVar = yield functionThatR         


        
相关标签:
2条回答
  • 2020-12-17 19:03

    Yes, co can do that. You'll have to wrap parent function inside co call:

    co(function *(){
        var someVar = yield functionThatReturnsAPromise();
    })()
    

    someVar inside will become resolved value. If promise gets rejected, error can be cought with basic try {} catch (e) {} statements.

    0 讨论(0)
  • 2020-12-17 19:12

    Typically a yield acts returns the same value to its own paused execution (left hand side of the yield function) as to the calling function of the generator. In this simple example counting from 1 to 5 example the input of the yield is the output of the yield to the generator function as well as to the generator's execution path:

    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
    }
    

    However, the calling function may also call the generator, but replace the output the last yield with another value or even throw an exception to the generator's execution. In the case of promise a function that returns a promise, may yield the result of that promise instead of the promise itself. So in this case:

    var someVar = yield functionThatReturnsAPromise();
         ^ output  !=   ^ input
    

    you want the yield to act as a function that takes a promise as an input and returns a resolved promise as an output to the generator function.

    It so happens co is able to do exactly this for you. All you need to do is feed your generator function to the co function:

    co(function *(){
        var someVar = yield functionThatReturnsAPromise();
    })
    

    To better understand how this works, here is an example of a function, that does the same thing as 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
      }
    }
    

    source is from Forbes Lindesay's now famous presentation about this concept

    0 讨论(0)
提交回复
热议问题