下面这段代码中,为何 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")
很疑惑啊。。。我把我的代码和版本什么的都贴出来,还有我的试验结果。。。我的结论还是第一个await
是正常 send
出去了的。
- 先贴结果
- 我的依赖环境
fastapi = "^0.110.0"uvicorn = {extras = ["standard"], version = "^0.28.0"}websockets = "^12.0"datasets = "^2.18.0"
- 我的示例代码
为了能明确看出前后顺序差异,我加入了时间戳 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
的信息。
你可以拿我的去你那里在试验一下。。。
在 Python 中,await
关键字用于挂起当前异步函数的执行,直到等待的异步操作完成。在你提供的代码中,await ws.send(1)
和 await ws.send(2)
会等待它们各自的发送操作完成。然而,它们并不会阻塞 load_dataset("beans")
的执行,因为 load_dataset
函数也是异步的(假设它使用了 async
和 await
)。
这意味着,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的位置 怎么解释呢