成功回调 给 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())