为什么我只能在异步函数内部使用AWAIT关键字? [英] Why can I only use the await keyword inside of async function?

查看:22
本文介绍了为什么我只能在异步函数内部使用AWAIT关键字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有如下代码

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_thing()的主体正在做一些可以导致其 暂停。

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

This article详细说明(您可以从"已经说到重点"段落开始)。

但是,如果我将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)

这篇关于为什么我只能在异步函数内部使用AWAIT关键字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆