当前位置: 首页 > 面试题库 >

为什么我只能在异步函数内部使用await关键字?

葛炯
2023-03-14
问题内容

假设我有这样的代码

async def fetch_text() -> str:
    return "text "

async def show_something():
    something = await fetch_text()
    print(something)

没关系 但是然后我想清除数据,所以我这样做

async def fetch_text() -> str:
    return "text "

def fetch_clean_text(text: str) -> str:
    text = await fetch_text()
    return text.strip(text)

async def show_something():
    something = fetch_clean_text()
    print(something)

(我可以清理其中的文本show_something(),但让我们假设它show_something()可以打印很多东西,并且不知道或不应该知道清理它们的正确方法。)

这当然是一个SyntaxError: 'await' outside async function。但是,如果该代码可以运行,则在await表达式未放置在协程函数内部的情况下,将在一个上下文中 执行
该表达式。为什么不允许这种行为?

我看到这种设计的一个专业人士。在后一个示例中,您看不到show_something()的身体正在做一些可能导致其暂停的操作。但是,如果要制作fetch_clean_text()协程,不仅会使事情复杂化,而且可能还会降低性能。拥有另一个本身不执行任何I
/ O的协程几乎没有什么意义。有没有更好的办法?


问题答案:

我看到这种设计的一个专业人士。在我的后一个示例中,您看不到show_something()的主体正在执行可能会导致其暂停的操作。

这就是它如此设计的原因。编写并发代码可能非常棘手,并且异步作者认为始终显式标记代码中的挂起位置至关重要。

本文详细介绍了它(您可以从“ Get
To the Point Already”段落开始)。

但是,如果要使fetch_clean_text()成为协程,不仅会使事情复杂化,而且可能还会降低性能。

在处理I / O时,几乎只需要协程。与使用协程相比,I / O总是比开销花费更多的时间。因此,我想可以说-不,与您已经处理的I /
O相比,使用协程不会浪费大量执行时间。

有没有更好的办法?

我只能建议的唯一方法是:将处理I / O(异步部分)的逻辑与其余代码(同步部分)分开。

from typing import Awaitable

def clean_text(text: str) -> str:
    return text.strip(text)

async def fetch_text() -> Awaitable[str]:
    return "text "

async def fetch_clean_text(text: str) -> Awaitable[str]:
    text = await fetch_text()
    return clean_text(text)

async def show_something():
    something = await fetch_clean_text()
    print(something)


 类似资料:
  • 问题内容: 我试图将两个异步函数链接在一起,因为第一个具有条件返回参数,导致第二个运行或退出模块。但是,我发现规格中找不到奇怪的行为。 这是我的代码的混帐摘要(您可以在此处查看完整的范围),该代码只是检查玩家是否已经在大厅中,但这无关紧要。 接下来,我们有这个异步功能。 如果,则无需运行此功能。 我试着做 我希望这将等待结果,以便可以有条件地运行,但是我收到了没有具体细节的类型错误。 为什么您不能

  • 问题内容: 有没有办法使javascript 关键字在函数外部起作用?我希望能够冻结整个调用堆栈(而不是仅冻结函数的其余部分),以便在特定的Promise返回值后可以恢复。令人遗憾的是,目前尚未确定或尚未实施类似这样的强大功能。我试图使nodent.js正常工作,但是由于我的自定义加载程序和动态功能,不幸的是不切实际。 问题答案: 如果您正在寻找黑客,而不是适当的基于诺言的并发解决方案,请看一下节

  • 我在一个函数中有这样的代码块: 它获取一些数据,然后对数据运行验证()。 但是,我对数据的验证实际上也是异步的,因为它是根据一个json模式来验证数据的,而json模式位于一个独立的json文件中,所以它必须首先读取该文件。 我使用了一个承诺来读取文件内容,然后进行验证: 如何编辑此问题中的顶部代码块以解释if语句()中的异步函数?

  • 我得到以下警告... 警告1此异步方法缺少await运算符,将同步运行。考虑使用'await'运算符来等待非阻塞API调用,或者使用'await task.run(...)'在后台线程上执行CPU绑定的工作。

  • 我有一个简短的Node.js脚本,我需要另一个包并从中调用一个异步函数,然后想要打印返回值。如果我只是来自顶层的返回值,那么我会收到一个错误,说我只能在异步函数本身中使用。所以很明显的方法是这样的: 或者: 或者: (聊天 https://chat.stackoverflow.com/transcript/message/54186176#54186176 中归功于VLAZ) 这有效 - 但我想更

  • 我是个新手,一直在浏览源代码,发现: 这个函数定义这样的内部函数有什么原因吗?为什么不直接写:

  • 问题内容: 我目前正在与Sierra&Bates一起准备S(O)CJP。 关于内部类(局部或匿名方法),他们说我们无法访问局部变量,因为它们在类驻留在堆上时仍位于堆栈中,并且可以由方法返回,然后尝试访问这些变量由于该方法已结束,因此它们已在堆栈中,但已不存在… 众所周知,我们可以使用final关键字来绕开它。这就是他们在书中所说的,但是他们并没有真正解释final关键字的作用……据我所知,在方法局

  • 问题内容: 我正在查看Drupal 7的资源,发现了一些以前从未见过的东西。我在php手册中做了一些初步的了解,但没有解释这些示例。 关键字对函数内部的变量有什么作用? 问题答案: 它使函数记住多次调用之间给定变量的值(在您的示例中)。 您可以将其用于不同的目的,例如: 在此示例中,只能执行一次。即使会发生多次呼叫。