【问题标题】:The synchronicity of for...await loops in JavaScriptJavaScript 中 for...await 循环的同步性
【发布时间】:2020-06-07 13:13:13
【问题描述】:

我试图在 JavaScript 中可视化 for...await 循环的同步性。

似乎在async 生成器函数中both yieldawait 将停止进度并提示微任务的继续。

换句话说:在这种情况下,产生始终是异步的,即使您不使用 await 关键字

这是正确的吗? async 生成器函数在 for...await 循环的上下文之外呢?

下面使用then 创建了一个紧密的微任务循环,以尝试查看任务是如何交错的。

function printNums() {
    let counter = 0
    function go() {
        console.log(counter++)    
        if(counter < 10) Promise.resolve().then(go)
    }
    Promise.resolve().then(go)
}

printNums()

async function asyncFn() {
    console.log('inside asyncFn 1')
    await null
    console.log('inside asyncFn 2')
}

asyncFn()

const asyncIterable = {
    async *[Symbol.asyncIterator]() {
        console.log('inside asyncIterable 1')
        yield '⛱'
        console.log('inside asyncIterable 2')
        await null
        console.log('inside asyncIterable 3')
        yield '????'
        yield '????'
    }
}

async function printAsyncIterable() {
    for await(let z of asyncIterable) {
        console.log(z)
    }
}
printAsyncIterable()

【问题讨论】:

  • 正确,但如您所知,您应该将问题限制为一个问题。

标签: javascript


【解决方案1】:

换句话说:在这种情况下,产生始终是异步的,即使您不使用 await 关键字

是的。在异步生成器函数中,表达式

yield value

表现得好像你写过

await (yield (await value))

你不能产生承诺,也不能接受承诺,它们总是被next()调用自动解包。

【讨论】:

  • 好的,所以yield new Promise((res) =&gt; setTimeout(() =&gt; res('a'), 1000)) 上的进度被阻止,并且解决的结果被传递。另外:我认为yield await new Promise((res) =&gt; setTimeout(() =&gt; res('a'), 1000)) 是有效的语法,只是for...await 循环解开它。该函数的另一个使用者可能会做一些不同的事情?
  • 不,这对所有消费者都是一样的,是异步生成器本身进行解包而不是 for await … of 循环。 yield await 是有效的语法,但毫无意义。
猜你喜欢
  • 2023-04-09
  • 2022-10-16
  • 1970-01-01
  • 1970-01-01
  • 2021-05-18
  • 2014-07-06
  • 2016-01-24
  • 2014-07-09
  • 1970-01-01
相关资源
最近更新 更多