JavaScript 和 Python Promise/Awaitable 评估之间的区别

Mar*_*hac 5 javascript python concurrency promise async-await

我一直在尝试学习具有 Python 背景的 JS 并发模型。

在 Python 中运行以下命令:

async def myFunction():
    print("abc")

myFunction()
Run Code Online (Sandbox Code Playgroud)

不会打印任何内容。在 JavaScript 中运行以下命令:

async function myFunction() {
    console.log("abc")
}

myFunction()
Run Code Online (Sandbox Code Playgroud)

将打印"abc". 在这两种情况下我都没有await myFunction,但评价却不同。

我明白为什么Python程序什么也不打印。myFunction是一个不解析任何内容的协程函数,更具体地说,它返回一个Awaitable[None]. 但要真正执行这个可等待的副作用,我必须等待它。

我还读过承诺是否被延迟评估?答案是否定的,谈论如何保证对 Promise 的急切评估。

尽管我已经分别研究了这两种并发模型,但它们的差异仍然令人困惑。虽然这里的对比的总体清晰性会非常有帮助,但我也确实有一个具体的问题:在 JavaScript 中是否有一个点需要等待 aPromise解析为空,并且应该只执行它的副作用?换句话说,即使它们在这里给出了相同的输出,但在不同的情况下,它们的行为是否可能存在差异await myFunction()myFunction()

Ant*_*des 5

async def myFunction():
    print("abc")

awaitable = myFunction()
Run Code Online (Sandbox Code Playgroud)

在 Python 中,myFunction()返回一个等待对象。代码还没有运行。.send()它仅在您对可等待对象执行方法 () 时运行:

awaitable.send(None)
Run Code Online (Sandbox Code Playgroud)

您通常不使用.send(),这些机制是隐藏的。您只需使用await myFunction()or asyncio.get_event_loop().run_until_complete(myFunction()),这将在幕后执行该函数的代码。

在 JavaScript 中,异步函数返回一个承诺。MDN JS 参考资料

JavaScript 中的 Promise 代表已经发生的流程

因此,当您在 JavaScript 中调用 async 函数时,该函数的代码开始运行,并在某个时刻返回一个 Promise。MDN JS 参考文献对此的描述如下:

异步函数的主体可以被认为是被零个或多个等待表达式分割。顶级代码,直到并包括第一个等待表达式(如果有),都是同步运行的。这样,没有await表达式的异步函数将同步运行。但是,如果函数体内有await 表达式,则异步函数将始终异步完成。

考虑到这一切,我不明白为什么如果你只想要它的副作用(除非调用者需要在继续之前发生副作用),你会等待异步 JS 函数。