为什么不能放弃承诺?

时间:2018-10-21 12:57:53

标签: javascript ecmascript-6 yield

我有以下代码:

object = {
    getPastEvents: () => Promise.resolve([1,2,3])
}

function* fetchPastEvents() {
    const values = yield object.getPastEvents()
    console.log(values)
}

const events = fetchPastEvents()
events.next()
events.next()

现在,我想知道如何创建返回定义的getPastEvents的函数values。目前,valuesundefined。我以为yield可以解决async await之类的承诺。

3 个答案:

答案 0 :(得分:5)

调用.next时,将继续运行生成器功能。如果要使用特定值恢复它,请将一个值传递到.next中。因此,如果您想复制redux-saga解析诺言然后恢复生成器的行为,则需要采用第一次调用.next所产生的诺言,等待诺言通过使用其{{1 }}方法,然后使用解析后的值调用.then

.next

我建议您不要自己这样做。如果这是您所说的传奇,请通过redux传奇运行它,您将免费获得此行为。或者像其他人提到的那样,co库实现了类似的功能。

答案 1 :(得分:3)

  

我认为yield可以解决async await之类的诺言。

否,yield用于生成一个生成器函数,这意味着它会在此时停止函数执行,将右侧的表达式返回给.next()的调用方,然后采用传递给下一个.next(value)调用的值来继续执行。这是异步的,但与async / await没有任何关系。但是,您可以产生一个承诺,并在该承诺解决时调用下一个.next(value)

 async function co(generator) {
   let iterator = generator();
   let done, value;
   do {
     ({ done, value } = iterator.next(await value);
   } while(!done);
   return value;
}

可用作:

 co(function* doAsync() {
   let result = yield somePromise();
   console.log(result);
});

但是我不知道这怎么有用。

答案 2 :(得分:1)

在生成器中使用收益率并不能保证等到承诺被完全兑现。

要使您的示例可行,您必须编写代码以调用实现可迭代协议的对象的下一个方法。

function runGenerator(asyncGen) {
    const gen = asyncGen();
    let returnValue;

    (function iterate(value){
        returnValue = gen.next(value);

        if(!returnValue.done) {
            returnValue.value.then(iterate);
        }
    })();
}

const object = {
    getPastEvents: () => Promise.resolve([1,2,3])
};

runGenerator(function*() {
    const values = yield object.getPastEvents();
    console.log(values);
});

请注意,这只是简单的实现,如果要使用实际项目,则必须检查更多条件。

我建议您使用co模块,而不是仅仅为此实现自己的模块。


请注意,Async&Await与这种方法非常相似,它们都需要有约定的API。

但是要使用Async&Await,请确保您的JavaScript引擎支持,否则您必须进行转换才能使其在较旧的引擎中运行。

但是使用生成器将可在大多数现代JavaScript引擎中使用,这是相当古老的规范(ES6)。

一般来说,转译Async&Await会产生大量代码,如果您想将内容的大小减小到最小,则可能是个问题。

ES6 Generator和ES7 Async&Await的主要区别在于ES6 Generator不能使用“箭头功能”,这在某些情况下确实很关键(但是在进入生成器功能的上下文之前,您必须将“ this”引用保存在某个地方), ES7异步功能可以做到这一点。

请注意,ES7 Async&Await只是Promise API的语法糖,但ES6生成器不是。

相关问题