2014-02-18 56 views
6

我试图找出如何通过yield得到承诺的价值,可能与“合作”承诺的价值:获得通过产量&CO

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

被调用的函数是不是一台发电机,只是一个正常的功能。与上面,someVar == Promise,但我想解决的价值。 co或其他一些图书馆是否有办法做到这一点?

+0

不,这不是真的'someVar == Promise'。 'somevar'等于通过调用迭代器的函数作为参数传递给'next'的值,它在获得前一个'next'的赋值后。 – 2015-11-29 13:13:39

+0

@torazaburo - 你是对的,但这是一个近2岁的回答问题,你只是增加了噪音......没有与实际问题没有关系的细节无关 –

回答

7

是的,co可以做到这一点。你必须包裹内co调用父函数:

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

someVar内将成为解决价值。如果承诺被拒绝,错误可能与基本的try {} catch (e) {}陈述有关。

+1

对我而言返回'Promise { } – Marek

7

对于生成器的调用函数,yield行为通常返回与其自身暂停执行(yield函数的左侧)相同的值。在这个简单的例子计数从1到5的例子收率的输入是屈服到发电机功能的输出以及向所述发电机的执行路径:

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 
} 

然而,调用函数也可以调用生成器,但用另一个值替换最后一个yield的输出,或者甚至向生成器的执行抛出异常。如果承诺一个函数返回一个承诺,可能会产生该承诺的结果,而不是承诺本身。因此,在这种情况下:

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

你想要的收益率作为接受一个承诺作为输入,并返回一个解决的承诺作为输出为发电机功能的函数。

恰巧co能够为你做到这一点。所有你需要做的是饲料的发电机功能的co功能:

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

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

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

+1

*通常,yield对于生成器的调用函数而言,其作用是将相同的值返回到其自己的暂停执行(yield函数的左侧)。在这个简单的例子中,yield的输入是yield函数的输出以及生成器的执行路径*。其实我无法解析这句话。但是,我认为这是错误的。 – 2015-11-29 13:16:50

+0

你不能在你的非生成器函数inc中使用yield。 –

+1

@HåvardGeithus固定 –