python asyncio使用async def添加_done_回调

python asyncio使用async def添加_done_回调,python,python-3.x,async-await,python-asyncio,coroutine,Python,Python 3.x,Async Await,Python Asyncio,Coroutine,我有两个函数:第一个,def_a,是一个异步函数,第二个是def_b,它是一个常规函数,通过def_a作为add_done_回调函数的回调进行调用 我的代码如下所示: import asyncio def def_b(result): next_number = result.result() # some work on the next_number print(next_number + 1) async def def_a(number): await

我有两个函数:第一个,
def_a
,是一个异步函数,第二个是
def_b
,它是一个常规函数,通过
def_a
作为
add_done_回调
函数的回调进行调用

我的代码如下所示:

import asyncio

def def_b(result):
    next_number = result.result()
    # some work on the next_number
    print(next_number + 1)

async def def_a(number):
    await some_async_work(number)
    return number + 1

loop = asyncio.get_event_loop()
task = asyncio.ensure_future(def_a(1))
task.add_done_callback(def_b)
response = loop.run_until_complete(task)
loop.close()
async def def_b(result):
    next_number = result.result()
    # some asynchronous work on the next_number
    print(next_number + 1)
这是完美的工作

当第二个函数
def_b
变为异步时,问题就开始了。现在看起来是这样的:

import asyncio

def def_b(result):
    next_number = result.result()
    # some work on the next_number
    print(next_number + 1)

async def def_a(number):
    await some_async_work(number)
    return number + 1

loop = asyncio.get_event_loop()
task = asyncio.ensure_future(def_a(1))
task.add_done_callback(def_b)
response = loop.run_until_complete(task)
loop.close()
async def def_b(result):
    next_number = result.result()
    # some asynchronous work on the next_number
    print(next_number + 1)
但是现在我不能将它提供给
add\u done\u回调
函数,因为它不是一个常规函数


我的问题是-如果
def_b
是异步的,我是否可能以及如何向
add_done_回调
函数提供
def_b
。使用协同程序时,您可以通过多种方式,例如:

import asyncio


async def my_callback(result):
    print("my_callback got:", result)
    return "My return value is ignored"


async def coro(number):
    await asyncio.sleep(number)
    return number + 1


async def add_success_callback(fut, callback):
    result = await fut
    await callback(result)
    return result


loop = asyncio.get_event_loop()
task = asyncio.ensure_future(coro(1))
task = add_success_callback(task, my_callback)
response = loop.run_until_complete(task)
print("response:", response)
loop.close()

请记住,
add\u done\u callback
仍将在将来引发异常时调用回调(但调用
result.result()
将引发异常)

这只适用于未来的一个作业,如果您有多个异步作业,它们将相互阻止,更好的方法是使用asyncio。as_completed()迭代未来列表:

import asyncio

async def __after_done_callback(future_result):
    # await for something...
    pass

async def __future_job(number):
    await some_async_work(number)
    return number + 1

loop = asyncio.get_event_loop()
tasks = [asyncio.ensure_future(__future_job(x)) for x in range(100)]  # create 100 future jobs

for f in asyncio.as_completed(tasks):
    result = await f
    await __after_done_callback(result)

loop.close()

出于好奇,感谢您分享使用Sure future而不是Wait my_coro在my_callback
Sure_future(coro)
中的好处是什么?只需排队等待
coro()
,以便以后执行,而不会立即启动
coro()
。应使用asyncio.create_task()而不是asyncio.Sure_future()在Python 3.7+中,为什么这是正确的答案。我认为应该使用
asyncio。确保回调函数中的\u future
是正确的。