RuntimeWarning:从未等待协程。如何异步/等待回调
RuntimeWarning: coroutine was never awaited. How to async / await a callback
我有一个 class 服务于网络套接字,并听取 PostgreSQL。使用 asyncpg,当我尝试使用 add_listener 时,出现错误:RuntimeWarning: coroutine was never awaited。如何异步/等待回调。我尝试添加 "await self.listener" 但它不起作用。
有没有办法用另一种方式处理这个问题?
import asyncio
import http
import websockets
import asyncpg
class App(object):
def __init__(self, loop):
self.loop = loop
self.ws_list = []
self.conn = None
async def ws_handler(self, ws, path):
if self.conn is None:
self.conn = await asyncpg.connect(user='xxx', password='xxx', database='pgws', host='127.0.0.1')
await self.conn.add_listener('todo_updates', self.listener)
print('new socket!!!')
self.ws_list.append(ws)
while True:
await asyncio.sleep(1)
async def listener(self, conn, pid, channel, payload):
print(payload)
for ws in self.ws_list:
task = asyncio.create_task()
await ws.send(payload)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
app = App(loop)
start_server = websockets.serve(app.ws_handler, 'localhost', 8766)
app.loop.run_until_complete(start_server)
app.loop.run_forever()
问题是您传递给 asyncpg.Connection.add_listener()
is a coroutine function 的回调,但它应该是一个简单的同步函数。 asyncpg 不会引发错误,因为从技术上讲它仍然是一个可调用的,它需要一个连接、pid、通道和有效负载,但它在被调用时的行为并不像您预期的那样。
要从同步回调中调用异步函数(事件循环已经 运行ning),您需要使用类似 asyncio.create_task()
(in Python >=3.7) or loop.create_task()
(in Python >=3.4.2) or asyncio.ensure_future()
的东西(在 Python >= 3.4.4),像这样:
class App:
... # Your other code here
def listener(self, conn, pid, channel, payload):
print(payload)
for ws in self.ws_list:
asyncio.create_task(ws.send(payload))
请注意 asyncio.create_task()
(以及上述其他函数)会立即 return,不会等待任务完成。在其他地方 await
秒后,任务将 安排 到 运行。
我有一个 class 服务于网络套接字,并听取 PostgreSQL。使用 asyncpg,当我尝试使用 add_listener 时,出现错误:RuntimeWarning: coroutine was never awaited。如何异步/等待回调。我尝试添加 "await self.listener" 但它不起作用。
有没有办法用另一种方式处理这个问题?
import asyncio
import http
import websockets
import asyncpg
class App(object):
def __init__(self, loop):
self.loop = loop
self.ws_list = []
self.conn = None
async def ws_handler(self, ws, path):
if self.conn is None:
self.conn = await asyncpg.connect(user='xxx', password='xxx', database='pgws', host='127.0.0.1')
await self.conn.add_listener('todo_updates', self.listener)
print('new socket!!!')
self.ws_list.append(ws)
while True:
await asyncio.sleep(1)
async def listener(self, conn, pid, channel, payload):
print(payload)
for ws in self.ws_list:
task = asyncio.create_task()
await ws.send(payload)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
app = App(loop)
start_server = websockets.serve(app.ws_handler, 'localhost', 8766)
app.loop.run_until_complete(start_server)
app.loop.run_forever()
问题是您传递给 asyncpg.Connection.add_listener()
is a coroutine function 的回调,但它应该是一个简单的同步函数。 asyncpg 不会引发错误,因为从技术上讲它仍然是一个可调用的,它需要一个连接、pid、通道和有效负载,但它在被调用时的行为并不像您预期的那样。
要从同步回调中调用异步函数(事件循环已经 运行ning),您需要使用类似 asyncio.create_task()
(in Python >=3.7) or loop.create_task()
(in Python >=3.4.2) or asyncio.ensure_future()
的东西(在 Python >= 3.4.4),像这样:
class App:
... # Your other code here
def listener(self, conn, pid, channel, payload):
print(payload)
for ws in self.ws_list:
asyncio.create_task(ws.send(payload))
请注意 asyncio.create_task()
(以及上述其他函数)会立即 return,不会等待任务完成。在其他地方 await
秒后,任务将 安排 到 运行。