asyncio之异步生产结果

异步生产结果

一个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相关章节

文章目录
  1. 1. 等待Future
  2. 2. Future回调
|