异步函数运行完毕后,我正在尝试调用回调
这是我想做的事的一个例子:
import asyncio
async def asyncfunction():
print('Hello')
await asyncio.sleep(10)
print('World')
return 10
def callback(n):
print(f'The async function returned: {n}')
loop = asyncio.get_event_loop()
# Will block the print until everything is done
callback(loop.run_until_complete(asyncfunction()))
print('Hey')
这是做什么的
Hello
World
The async function returned: 10
Hey
这就是我想要的事情
编辑:“嘿”的位置并不重要,只要它不必等待异步功能完成
Hello
Hey
World
The async function returned: 10
编辑:经过一些测试,我发现了一种可以实现自己想要的方式,尽管我不知道这是否是最好的方式
import asyncio
import threading
async def asyncfunction():
print('Hello')
await asyncio.sleep(10)
print('World')
return 10
def callback(n):
print(f'The async function returned: {n}')
def wrapper(loop):
callback(loop.run_until_complete(asyncfunction()))
loop = asyncio.get_event_loop()
thr = threading.Thread(target=wrapper,args=(loop,))
thr.start()
print('Hey')
答案 0 :(得分:3)
免责声明:Following code creates different threads for each function.
这在某些情况下可能很有用,因为它更易于使用。但要知道它不是异步的,而是使用多线程产生异步的错觉,即使装饰者建议这样做。
要使任何函数非阻塞,只需复制装饰器并使用回调函数作为参数装饰任何函数。回调函数会接收函数返回的数据。
import asyncio
import requests
def run_async(callback):
def inner(func):
def wrapper(*args, **kwargs):
def __exec():
out = func(*args, **kwargs)
callback(out)
return out
return asyncio.get_event_loop().run_in_executor(None, __exec)
return wrapper
return inner
def _callback(*args):
print(args)
# Must provide a callback function, callback func will be executed after the func completes execution !!
@run_async(_callback)
def get(url):
return requests.get(url)
get("https://google.com")
print("Non blocking code ran !!")
答案 1 :(得分:1)
要获得该命令,您需要在print('Hey')
之后继续执行协程。您还需要在'Hey'
休眠时在{lull”中打印asyncfunction
。这基本上只能由事件循环本身来调度;因为asyncfunction
是您所知道的所有信息的黑匣子,并且您不知道它在等待什么,或者为什么或在它处于休眠状态时可以从中明确地获得控制权。
因此,将asyncfunction
和print('Hey')
都作为异步任务执行,并且希望主要执行计划,以使“ Hey”计划在{{1 }}正在睡觉。
asyncfunction
val, *_ = loop.run_until_complete(asyncio.gather(
asyncfunction(),
asyncio.coroutine(print)('Hey')
))
callback(val)
将asyncio.coroutine(print)
转换为print
函数,并且async
在事件循环上同时安排两个时间,并且可能 gather
将在print
处于休眠状态时执行。
答案 2 :(得分:0)
将线程与asyncio一起使用只是令人困惑,而且很可能不是您想要的。 run_until_complete
是阻塞调用之一,可能应该是asyncio
程序中的最后一条语句。
要在调用异步函数后添加代码,只需创建一个包装器
async def myfunc():
n = await asyncfunction()
callback(n)
loop.run_until_complete(myfunc()) # from python 3.7, asyncio.run(myfunc())
如果您只想安排一些代码异步运行并继续执行其他操作,请创建一个任务并等待最后
async def a_main():
task = asyncio.ensure_future(myfunc()) # from python 3.7, asyncio.create_task(...)
print("Hey")
# Anything else to run
await task # wait for the task to complete
loop.run_until_complete(a_main())