Future 在状态为done时候可以执行一些回调函数, 按照注册时的顺序回调。注意:回调函数返回为None
import time
import asyncio
async def do_some_work(x):
print("Hello:",x)
return "work is done for {}".format(x)
start = time.perf_counter()
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
tasks = []
for i in range(5):
coroutine = do_some_work(i)
task = asyncio.ensure_future(coroutine)
# task = loop.create_task(coroutine)
tasks.append(task)
loop.run_until_complete(asyncio.wait(tasks))
for task in tasks:
print(task.result())
loop.close()
end = time.perf_counter()
print("total run time:", end-start)
结果如下
Hello: 0
Hello: 1
Hello: 2
Hello: 3
Hello: 4
work is done for 0
work is done for 1
work is done for 2
work is done for 3
work is done for 4
total run time: 0.0
试试callback
import time
import asyncio
now = lambda : time.time()
async def do_some_work(x):
print("Hello:", x)
return "work is done for {}".format(x)
def callback(future):
time.sleep(1)
print("callback:", future.result())
start = now()
loop = asyncio.new_event_loop() # 创建新的loop
asyncio.set_event_loop(loop) # 解决loop argument must agree with Future报错问题
tasks = []
for i in range(5):
coroutine = do_some_work(i)
task = asyncio.ensure_future(coroutine)
task.add_done_callback(callback)
tasks.append(task)
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
end = now()
print("total run time:", end-start)
task.add_done_callback(callback) 意思是 task执行后调用callback这个回调函数,获取协程返回值。
Hello: 0
Hello: 1
Hello: 2
Hello: 3
Hello: 4
callback: work is done for 0
callback: work is done for 1
callback: work is done for 2
callback: work is done for 3
callback: work is done for 4
total run time: 5.003510236740112
有时候回调函数需要输入多个参数,可以用functools.partial转成偏函数。
import asyncio
import functools
async def do_some_work(x):
print("Hello:",x)
return "work is done for {}".format(x)
def done_callback(loop, future):
loop.stop()
print("callback:", future.result())
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
futus = asyncio.gather(do_some_work(1), do_some_work(2))
futus.add_done_callback(functools.partial(done_callback, loop))
loop.run_forever()
Hello: 2
Hello: 1
callback: ['work is done for 1', 'work is done for 2']