如何使用asyncio.wait_for到run_until_complete同步调用Python中的async方法
How to use asyncio.wait_for to run_until_complete to synchronously call async method in Python
为了允许通过 Python websocket 接收数据超时,FAQ: How do I set a timeout on recv()? 建议使用异步接收数据:
await asyncio.wait_for(websocket.recv(), timeout=10)
由于我接收数据的功能不是异步的,我已经将 调整为 运行 asyncio 循环直到接收到数据或超时发生:
loop.run_until_complete(asyncio.wait_for(ws.recv(), timeout=10))
不幸的是,此声明似乎无效,因为发生了以下异常:
An asyncio.Future, a coroutine or an awaitable is required
对我来说,asyncio.wait_for
似乎不是 run_until_complete
的有效参数,尽管 documentation 清楚地显示了一个 await
的示例。
我在这里遗漏了什么 - 在同步方法中使用 asyncio.wait_for
的正确方法是什么?
您需要 loop.run_until_complete
使用协程。为此,您可以将接收代码包装到一个异步函数中:
async def receive_message():
return await asyncio.wait_for(ws.recv(), timeout=10)
loop.run_until_complete(receive_message())
这是一个完整的工作代码:
import asyncio
import websockets
URI = "ws://0.0.0.0:8765"
TIMEOUT = 2
async def create_ws():
return await websockets.connect(URI)
async def receive_message():
ws = await create_ws()
print("Connected")
message = await asyncio.wait_for(ws.recv(), timeout=TIMEOUT)
print(f"Received message in less than {TIMEOUT} seconds: {message}")
if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(receive_message())
Python 中有两个常用的 websocket 模块可用。
而 websockets is imported with import websockets
there is also the websocket-client 是用 import websocket
.
导入的
两个模块提供几乎相同的 API 其中 ws.recv()
允许接收数据。
模块彼此如此相似的事实可能会引起混淆,这至少会导致我的例外。
虽然 websockets 能够进行异步操作,但 websocket 不能。这意味着我的声明
loop.run_until_complete(asyncio.wait_for(ws.recv(), timeout=10))
将仅适用于 websockets,如果与 websocket 一起使用,例外情况
An asyncio.Future, a coroutine or an awaitable is required
会发生。
为了允许通过 Python websocket 接收数据超时,FAQ: How do I set a timeout on recv()? 建议使用异步接收数据:
await asyncio.wait_for(websocket.recv(), timeout=10)
由于我接收数据的功能不是异步的,我已经将
loop.run_until_complete(asyncio.wait_for(ws.recv(), timeout=10))
不幸的是,此声明似乎无效,因为发生了以下异常:
An asyncio.Future, a coroutine or an awaitable is required
对我来说,asyncio.wait_for
似乎不是 run_until_complete
的有效参数,尽管 documentation 清楚地显示了一个 await
的示例。
我在这里遗漏了什么 - 在同步方法中使用 asyncio.wait_for
的正确方法是什么?
您需要 loop.run_until_complete
使用协程。为此,您可以将接收代码包装到一个异步函数中:
async def receive_message():
return await asyncio.wait_for(ws.recv(), timeout=10)
loop.run_until_complete(receive_message())
这是一个完整的工作代码:
import asyncio
import websockets
URI = "ws://0.0.0.0:8765"
TIMEOUT = 2
async def create_ws():
return await websockets.connect(URI)
async def receive_message():
ws = await create_ws()
print("Connected")
message = await asyncio.wait_for(ws.recv(), timeout=TIMEOUT)
print(f"Received message in less than {TIMEOUT} seconds: {message}")
if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(receive_message())
Python 中有两个常用的 websocket 模块可用。
而 websockets is imported with import websockets
there is also the websocket-client 是用 import websocket
.
两个模块提供几乎相同的 API 其中 ws.recv()
允许接收数据。
模块彼此如此相似的事实可能会引起混淆,这至少会导致我的例外。
虽然 websockets 能够进行异步操作,但 websocket 不能。这意味着我的声明
loop.run_until_complete(asyncio.wait_for(ws.recv(), timeout=10))
将仅适用于 websockets,如果与 websocket 一起使用,例外情况
An asyncio.Future, a coroutine or an awaitable is required
会发生。