【问题标题】:Asynchronous Generators in Javascript: is there a difference between yielding a Promise and yielding an awaited Promise?Javascript 中的异步生成器:产生 Promise 和产生等待的 Promise 之间有区别吗?
【发布时间】:2019-02-14 21:42:04
【问题描述】:

我正在研究 ES9 中提出的异步生成器,以便能够掌握逻辑。

由于每个产生的值都用作返回对象中的值属性 - 由 Promise 包装 - 来自 next() 调用:

async function * asyncGen() {
    yield 1;
    yield 2; 
}

let asyncIterator = asyncGen();

asyncIterator.next(); // Promise fullfilled with {value: 1, done: false}

asyncIterator.next(); // Promise fullfilled with {value: 2, done: false}

我认为这对于 yield Promises 也是如此:

async function * asyncGen() {
    yield Promise.resolve(3);
    yield new Promise(done => setTimeout(done, 10000));
}

let asyncIterator = asyncGen();

asyncIterator.next();
// Expected: Promise fullfilled with {value: Promise fullfilled with 3, done: false}
// Get: Promise fullfilled with {value: 3, done: false}

asyncIterator.next();
// Expected: Promise fullfilled with
// {value: Promise pending for 10 seconds, then fullfilled with undefined, done: false}
// Get: Promise pending for 10 seconds,
// then fullfilled with {value: undefined, done: false}

因此,promise 合并在一起。这听起来不错,但我没想到是因为:

async function * asyncGen() {
    yield await Promise.resolve(3);
    yield await new Promise(done => setTimeout(done, 10000));
}

let asyncIterator = asyncGen();

asyncIterator.next(); // Promise fullfilled with {value: 3, done: false}

asyncIterator.next(); 
// Promise pending for 10 seconds,
// then fullfilled with {value: undefined, done: false}

这里合并更合理,因为 await 不能停止生成器,next() 调用必须返回一个 Promise。但是只有在等待生成器中的 Promise 完成时,才能完成该 Promise。

那么关键字 await 在同一个表达式中与关键字 yield 一起使用是完全没用的,还是我遗漏了一些重要的东西?

【问题讨论】:

标签: javascript asynchronous promise generator


【解决方案1】:

结合 await 和 yield 的一个有趣的方面是 await 不能阻止 yield 返回一个 Promise,但它可以阻止这个 Promise 被结算:

async function* asyncGenerator() {
    console.log('Start');
    const result = await doSomethingAsync(); // (A)
    yield 'Result: '+result; // (B)
    console.log('Done');
}

ES2018: asynchronous iteration Axel Rauschmayer 博士

【讨论】:

  • 谢谢,但我不是在谈论这个特殊情况。我同意使用 await 停止返回的承诺的可能性,因为这是可能发生的唯一合理的事情。
【解决方案2】:

异步生成器解包产生的 Promise 以避免 Promise(例如,由 next 方法返回的 Promise)(value 字段内的 Promise)。 JavaScript 语言始终远离的概念。

【讨论】:

    猜你喜欢
    • 2015-03-17
    • 1970-01-01
    • 1970-01-01
    • 2016-03-01
    • 2020-03-04
    • 2020-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多