异步函数完成后Python调用回调

mat*_*mat 5 python python-asyncio

我试图在异步函数运行完成后调用回调

这是我想做的一个例子:

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')
Run Code Online (Sandbox Code Playgroud)

这是它的作用:

Hello
World
The async function returned: 10
Hey
Run Code Online (Sandbox Code Playgroud)

这就是我想要它做的
编辑:“嘿”的位置并不重要,只要它不必等待异步函数完成即可

Hello
Hey
World
The async function returned: 10
Run Code Online (Sandbox Code Playgroud)

编辑:经过一些测试,我找到了一种可以实现我想要的功能的方法,尽管我不知道这是否是最好的方法

Hello
World
The async function returned: 10
Hey
Run Code Online (Sandbox Code Playgroud)

bal*_*lki 5

将线程与 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())
Run Code Online (Sandbox Code Playgroud)

如果您只想安排一些代码异步运行并继续执行其他操作,请创建一个任务并在最后等待

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())
Run Code Online (Sandbox Code Playgroud)


dec*_*eze 2

要获得该顺序,您需要在 后继续执行协程print('Hey')。您还需要在睡觉'Hey'时在“安静”时打印该信息asyncfunction。这本质上只能由事件循环本身来调度;因为asyncfunction对于您所知道的一切来说,since 是一个黑匣子,您不知道它在等待什么或为什么,或者在它休眠时可以明确地从它那里获取控制权。

因此,将asyncfunctionprint('Hey')作为异步任务执行,并且主要希望asyncfunction调度能够顺利进行,以便安排“Hey”在睡眠时运行。

val, *_ = loop.run_until_complete(asyncio.gather(
    asyncfunction(),
    asyncio.coroutine(print)('Hey')
))
callback(val)
Run Code Online (Sandbox Code Playgroud)

asyncio.coroutine(print)变成print一个async函数,并gather同时在事件循环上调度这两个函数,并且它可能会计算出将在睡眠print时执行。asyncfunction