asyncio的回调函数

成功回调 给 Task (Future) 添加回调函数

import asyncio
import functools

async def a():
    await asyncio.sleep(1)
    return "A"

async def b():
    await asyncio.sleep(1)
    return "B"

loop = asyncio.get_event_loop()
task_a = loop.create_task(a())
task_b = loop.create_task(b())


def callback(future):
    print(f'Result: {future.result()}')

def callback2(future, n):
    print(f'Result: {future.result()}, N: {n}')


task_a.add_done_callback(callback)

task_b.add_done_callback(functools.partial(callback2, n=100))

async def main():
    await asyncio.gather(task_a , task_b)


loop.run_until_complete(main())

调度回调

asyncio 提供了 3 个按需回调的方法,都在 Eventloop 对象上,而且也支持参数

call_soon

下一次事件循环中被回调,回调是按其注册顺序被调用的:


import asyncio
from functools import partial


def mark_done(future, result):
    print(f'Set to: {result}')
    future.set_result(result)


async def b1():
    loop = asyncio.get_event_loop()
    fut = asyncio.Future()
    loop.call_soon(mark_done, fut, 'the result')
    # 设置任务的结果:在 mark_done 里面设置
    loop.call_soon(partial(print, 'Hello', flush=True))
    # call_soon 支持参数
    loop.call_soon(partial(print, 'Greeting', flush=True))
    print(f'Done: {fut.done()}')
    # 首先 fut.done () 的结果是 False,因为还没到下个事件循环
    await asyncio.sleep(0)
    # sleep (0) 就可以切到下次循环,这样就会调用三个 call_soon 回调
    print(f'Done: {fut.done()}, Result: {fut.result()}')
    # 拿到之前在 mark_done 设置的值 

asyncio.run(b1())

call_later

安排回调在给定的时间 (单位秒) 后执行

import asyncio
from functools import partial


def mark_done(future, result):
    print(f'Set to: {result}')
    future.set_result(result)


async def b2(loop):
    fut = asyncio.Future()
    loop.call_later(1, mark_done, fut, 'the result')
    loop.call_later(0.5, partial(print, 'Hello'))
    loop.call_later(0.5, partial(print, 'Greeting'))
    print(f'Done: {fut.done()}')
    await asyncio.sleep(1.1)
    # 回调的延迟时间时间要<=sleep 的, 不然还没来及的回调程序就结束
    print(f'Done: {fut.done()}, Result: {fut.result()}')

loop = asyncio.get_event_loop()
loop.run_until_complete(b2(loop))


call_at

安排回调在给定的时间执行,注意这个时间要基于loop.time()获取当前时间

import asyncio
from functools import partial


def mark_done(future, result):
    print(f'Set to: {result}')
    future.set_result(result)



async def b3():
    loop = asyncio.get_event_loop()
    now = loop.time()
    fut = asyncio.Future()
    loop.call_at(now + 0.1, mark_done, fut, 'the result')
    loop.call_at(now + 0.2, partial(print, 'Hello', flush=True))
    loop.call_at(now + 0.2, partial(print, 'Greeting', flush=True))
    print(f'Done: {fut.done()}')
    await asyncio.sleep(0.5)
    print(f'Done: {fut.done()}, Result: {fut.result()}')


asyncio.run(b3())

Buy me a 肥仔水!