
在使用Python进行异步编程,特别是结合FastAPI和WebSocket时,理解函数执行顺序至关重要。本文分析一个常见误解:ws.send_text("1") 为什么看起来需要等待load_dataset("beans")完成才能执行?
代码示例及误解:
以下代码片段演示了这个问题:
from fastapi import FastAPI, WebSocket
from datasets import load_dataset
from datetime import datetime
app = FastAPI()
@app.websocket("/ws")
async def h(ws: WebSocket):
await ws.accept()
await ws.send_text(f"1: {datetime.now()}") # 似乎等待load_dataset完成?
dataset = load_dataset("beans")
await ws.send_text(f"2: {datetime.now()}")很多人误以为ws.send_text("1")必须等待load_dataset("beans")加载完成后才会执行。
立即学习“Python免费学习笔记(深入)”;
真相与实验:
为了验证,我们加入时间戳,并添加一个简单的HTML页面用于接收WebSocket消息:
<!DOCTYPE html>
<html>
<head>
<title>Chat</title>
<h1>WebSocket Chat</h1>
</head>
<body>
<ul id="messages"></ul>
<form id="sendMessageForm" onsubmit="sendMessage(event)">
<input type="text" id="messageText">
<button type="submit">Send</button>
</form>
<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>运行后,你会发现浏览器首先接收到"1: [时间戳]",服务器日志随后显示load_dataset("beans")正在执行。这证明ws.send_text("1")的执行并不依赖于load_dataset("beans")的完成。
原因分析:
await ws.send_text("1")是异步操作,它将消息发送到WebSocket连接后立即返回,不会阻塞后续代码的执行。load_dataset("beans")是一个耗时操作,但它也是异步执行的。 虽然load_dataset("beans")执行时间较长,但它不会阻塞ws.send_text("1")以及后续的ws.send_text("2"),只是ws.send_text("2")的执行时间会被延迟。
因此,ws.send_text("1")在load_dataset("beans")之前发送,但由于load_dataset("beans")的耗时特性,"2: [时间戳]"的发送会被延迟。 这解释了为什么浏览器先看到"1",而服务器日志显示数据加载仍在进行中。
以上就是为什么在Python异步编程中,ws.send_text("1") 会在 load_dataset("beans") 之前执行?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号