Await fetch 影响事件循环直到我评论它

问题描述 投票:0回答:1

目前正在研究处理NodeJS同步和异步功能的事件循环。据我了解,同步函数将首先执行,然后是异步函数。在下面的示例中,控制台日志同步执行,直到我从“fetchAPI”函数中删除await,然后同步函数将首先在“eventLoop”函数中执行,然后是异步函数。我试图理解为什么会发生这种行为。我错过了什么?

const experiment = async () =>{

    const num = 1

    setTimeout(()=>console.log("Hello from timeout"),0)
    console.log(num)

    const fetchAPI = await fetch("https://xxxxxxxxxxxx").then(x=>{
        console.log("Hello from API")    
        return x.json()
    })

    console.log(fetchAPI.id)
    
    console.log("String")

    Promise.resolve().then(()=>console.log("In promise"))

}

experiment()

API“https://xxxxxxxxxxxx”将返回一个随机数(下例中为139)。上一个函数的输出是:

1
Hello from timeout
Hello from API
139
String
In promise

每当我从函数“fetchAPI”中删除 await 时,它都会输出:

1
undefined
String
In promise
Hello from timeout
Hello from API
node.js asynchronous async-await event-loop
1个回答
0
投票

await
前面的
fetch()
告诉Javascript你想暂停执行包含函数直到
fetch()
返回的承诺实现。这就是为什么
fetch()
之后的代码直到
fetch()
完成后才执行的原因。

如果删除

await
,那么
fetch()
发送它的请求然后立即返回并且包含函数继续执行其他语句。当
fetch()
在未来的某个时间完成时,您已注册
.then()
处理程序的承诺将安排
.then()
处理程序在没有其他运行时通过事件系统运行。

所以,

await
暂停进一步执行
experiment()
功能,直到
fetch().then()
承诺履行。没有
await
experiment()
函数继续运行,无需等待
fetch()
操作完成。

一旦您让代码返回事件循环,

setTimeout(fn, 0)
就会运行。当您使用
await fetch()
时,会将解释器发送回事件循环,因此计时器会快速运行。

当您不使用

await
时,
experiment()
函数的其余部分将在控制返回事件循环之前执行,因此计时器回调将延迟到稍后。

Promise.resolve().then(()=>console.log("In promise"))
在计时器之前运行,因为准备好运行其处理程序的承诺在通用事件循环事物(例如计时器)之前提供服务(如果两者都准备好运行,您可以认为承诺具有更高的优先级)。

fetch().then()
不会立即运行,因为它有实际的异步工作要做,在它解决它的承诺并准备好运行之前需要实际时间,而
Promise.resolve().then(...)
立即解决它的承诺,因此立即准备好跑。

© www.soinside.com 2019 - 2024. All rights reserved.