异步生产结果
一个Future表示一个工作还未完成的结果对象。事件循环可以监视一个Future对象的状态直到它完成,允许应用程序的一部分等待另一部分完成一些工作。
等待Future
一个Future就像一个协程,所以任何用来等待协程的技术也能用来等待Future直到它被标记为完成。这个例子将Future传递给事件循环的run_until_complete()方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import asyncio def mark_done(future, result): print('setting future result to {!r}'.format(result)) future.set_result(result) event_loop = asyncio.get_event_loop() try: all_done = asyncio.Future() print('scheduling mark_done') event_loop.call_soon(mark_done, all_done, 'the result') print('entering event loop') result = event_loop.run_until_complete(all_done) print('returned result: {!r}'.format(result)) finally: print('closing event loop') event_loop.close() print('future result: {!r}'.format(all_done.result()))
|
当set_result()被调用时Future的状态被更改了,Future实例保留了给该方法设置的结果。
1 2 3 4 5 6 7 8
| $ python3 asyncio_future_event_loop.py scheduling mark_done entering event loop setting future result to 'the result' returned result: 'the result' closing event loop future result: 'the result'
|
在这个例子中也可以对Future使用await关键字。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import asyncio def mark_done(future, result): print('setting future result to {!r}'.format(result)) future.set_result(result) async def main(loop): all_done = asyncio.Future() print('scheduling mark_done') loop.call_soon(mark_done, all_done, 'the result') result = await all_done print('returned result: {!r}'.format(result)) event_loop = asyncio.get_event_loop() try: event_loop.run_until_complete(main(event_loop)) finally: event_loop.close()
|
Future的结果被await返回,所以可以使用相同的代码来处理协程和Future对象。
1 2 3 4 5
| $ python3 asyncio_future_await.py scheduling mark_done setting future result to 'the result' returned result: 'the result'
|
Future回调
除了跟协程的工作方式很像,Future在运行完成时可以设置回调。回调函数按照他们的被注册顺序被调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import asyncio import functools def callback(future, n): print('{}: future done: {}'.format(n, future.result())) async def register_callbacks(all_done): print('registering callbacks on future') all_done.add_done_callback(functools.partial(callback, n=1)) all_done.add_done_callback(functools.partial(callback, n=2)) async def main(all_done): await register_callbacks(all_done) print('setting result of future') all_done.set_result('the result') event_loop = asyncio.get_event_loop() try: all_done = asyncio.Future() event_loop.run_until_complete(main(all_done)) finally: event_loop.close()
|
回调应该只传入一个参数,就是Future实例,为了将参数传入被回调函数中,可以使用functools.partial()进行包装。
1 2 3 4 5 6
| $ python3 asyncio_future_callback.py registering callbacks on future setting result of future 1: future done: the result 2: future done: the result
|
本文翻译自《The Python3 Standard Library By Example》asyncio相关章节