当前位置: 首页 > 知识库问答 >
问题:

python - Python await 函数执行顺序的问题?

华凌
2024-03-12

下面这段代码中,为何 ws.send_text("1") 必须等待 load_dataset("beans") 加载完毕才会执行呢?

不应该是先执行 ws.send_text("1") 然后再执行 load_dataset("beans") 吗?

load_dataset 是一个 加载模型数据集的函数。
from fastapi import FastAPI, WebSocketfrom datasets import load_datasetapp = FastAPI()@app.websocket("/")async def h(ws: WebSocket):    await ws.accept()    await ws.send_text("1")    dataset = load_dataset("beans")    await ws.send_text("2")

共有2个答案

孙钱青
2024-03-12

很疑惑啊。。。我把我的代码和版本什么的都贴出来,还有我的试验结果。。。我的结论还是第一个await 是正常 send 出去了的。

  1. 先贴结果
  • 浏览器的结果
    image.png
  • 服务端的日志
    image.png
  1. 我的依赖环境
fastapi = "^0.110.0"uvicorn = {extras = ["standard"], version = "^0.28.0"}websockets = "^12.0"datasets = "^2.18.0"
  1. 我的示例代码

为了能明确看出前后顺序差异,我加入了时间戳 datetime.now() 在每个信息内容上。

from datetime import datetimefrom datasets import load_datasetfrom fastapi import FastAPI, WebSocketfrom fastapi.responses import HTMLResponseapp = FastAPI()html = """<!DOCTYPE html><html>    <head>        <title>Chat</title>    </head>    <body>        <h1>WebSocket Chat</h1>        <form action="" onsubmit="sendMessage(event)">            <input type="text" id="messageText" autocomplete="off"/>            <button>Send</button>        </form>        <ul id='messages'>        </ul>        <script>            var ws = new WebSocket("ws://localhost:8081/ws");            ws.onmessage = function(event) {                var messages = document.getElementById('messages')                var message = document.createElement('li')                var content = document.createTextNode(event.data)                message.appendChild(content)                messages.appendChild(message)            };            function sendMessage(event) {                var input = document.getElementById("messageText")                ws.send(input.value)                input.value = ''                event.preventDefault()            }        </script>    </body></html>"""@app.get("/")async def get():    return HTMLResponse(html)@app.websocket("/ws")async def h(ws: WebSocket):    await ws.accept()    await ws.send_text(f"1: {datetime.now()}")    dataset = load_dataset("beans")    print(f"time: {datetime.now()} => dataset: {dataset}")    await ws.send_text(f"2: {datetime.now()}")    while True:        data = await ws.receive_text()        await ws.send_text(f"Message text was: {data}, datetime: {datetime.now()}")

从我上面截图和我的实际操作来看,1 确实是先执行的,因为 html 接收到了 ws 的信息。
你可以拿我的去你那里在试验一下。。。

范瀚昂
2024-03-12

在 Python 中,await 关键字用于挂起当前异步函数的执行,直到等待的异步操作完成。在你提供的代码中,await ws.send(1)await ws.send(2) 会等待它们各自的发送操作完成。然而,它们并不会阻塞 load_dataset("beans") 的执行,因为 load_dataset 函数也是异步的(假设它使用了 asyncawait)。

这意味着,await ws.send(1) 发送消息后,控制权会立即返回给事件循环,事件循环会检查是否有其他可以并行执行的异步任务。在这种情况下,load_dataset("beans") 可以开始执行,因为它也是一个异步函数。

所以,ws.send(1) 不需要等待 load_dataset("beans") 加载完毕才会执行。实际上,ws.send(1)load_dataset("beans") 可能会并行执行,这取决于事件循环如何调度这些异步任务。

如果你发现 ws.send(1) 必须等待 load_dataset("beans") 加载完毕才会执行,可能是因为 load_dataset 函数实际上是同步的,或者它内部有一些同步操作导致它不能并行执行。你可以检查 load_dataset 函数的实现,确保它是异步的,并且没有阻塞操作。

另外,需要注意的是,由于 ws.send(1)load_dataset("beans") 是并行执行的,所以它们之间的执行顺序并不是固定的。也就是说,有时候 ws.send(1) 可能先执行,有时候 load_dataset("beans") 可能先执行,这取决于事件循环的调度和当前系统的负载情况。

如果你需要确保 ws.send(1)load_dataset("beans") 之前执行,你可以使用 await 来等待 ws.send(1) 的发送操作完成,然后再执行 load_dataset("beans")。但是,这仍然不能保证 ws.send(1)load_dataset("beans") 之前完成,因为这两个操作是并行执行的。如果你需要严格的执行顺序,你可能需要重新考虑你的代码结构,确保按照你想要的顺序执行操作。

 类似资料:
  • 问题内容: 我需要为测试设置执行顺序,因为我需要先验证一些数据。可以下订单吗? 谢谢 问题答案: 最好不要这样做。 测试应该是独立的。 要做您最想做的就是将代码放入测试调用的函数中。 像那样: 甚至拆分测试类,并将断言放入setUp函数中。 当我拆分班级时,我经常编写更多更好的测试,因为测试被拆分,并且在应该测试的所有情况下我都能看到更好的结果。

  • 问题内容: 指令功能的执行顺序是什么?该文档似乎没有解决此问题。 防爆 template / templateUrl(已评估) 控制器 编译 链接 从下面的答案中:http ://plnkr.co/edit/79iyKSbfxgkzk2Pivuak(插件显示嵌套和兄弟指令) 模板被解析 (在编译中对模板所做的更改会扩展到链接功能) 问题答案: 预链接功能:在链接子元素之前执行。执行DOM转换并不安

  • 此程序成功编译并显示以下输出。 问题 a)我不明白为什么alpha的构造函数没有首先被执行。 我相信“super()”会首先被每个子构造函数隐式调用...对吗?。 b)如果beta的构造函数已经执行,那么为什么打印“5”?(输出中的第二行) 第三行我有点理解(即alpha自己的变量将显示出来,因为还没有对“a”实例变量进行强制转换)

  • 我有一个包-'脚本' 根据剧本,我有两个类别——甲和乙 在一个类中,我有3个方法(@Test)按顺序编写- 在B班我有一种方法- TestNG. XML 在执行时——作为TestNG套件——右键单击TestNG XML并选择Run as a TestNG Suite 类B首先执行-这是因为类B中的@Test没有指定优先级,因此成为最高优先级 有没有办法让@Test的优先级只在类中起作用?为什么Te

  • 事件函数执行顺序 在 Unity 脚本中,有大量的事件函数以特定的顺序被执行。执行顺序描述如下: 编辑器 Reset 当第一次把脚本绑定到对象上,或者使用了 Reset 命令时,该事件被触发,用以初始化脚本的属性。 加载第一个场景 当某个场景开始时,下面的事件被触发(场景中的每个对象都会执行一次): Awake 该函数总是在所有 Start 函数之前被调用,并且只会在某个 prefab 被实例化之

  • 打印2的位置 怎么解释呢