import asyncio asyncio.as_completed(aws, *, loop=None, timeout=None)
aws
- множество объектов ожидания,loop=None
- параметр цикла (удален с версии Python 3.11),timeout=None
- максимальным количеством секунд ожидания.asyncio.as_completed
:Функция as_completed()
модуля asyncio
одновременно запускает объекты awaitable, переданные в итерации aws
, ждет их выполнения и по готовности любого начинает возвращать готовые объекты Future
.
Другими словами, функция asyncio.as_completed()
запускает и ждет выполнения переданных в нее задач/awaitable-объектов, и как только появляются результаты у какой-нибудь задачи, в реальном времени, начинает возвращать их в итераторе. Результаты извлекаются, запуском каждого объекта итератора при помощи оператора await
.
Например:
for coro in as_completed(aws): earliest_result = await coro # ...
Аргумент timeout
(float
или int
) в секундах, если он указан, можно использовать для управления максимальным временем ожидания, перед тем, как остановить не выполненные задачи, оставшихся в итераторе aws
.
Вызывает исключение asyncio.TimeoutError
, если тайм-аут наступает до того, как все задачи/awaitable-объекты будут выполнены.
Изменено в Python 3.8: аргумент
loop
устарел и будет удален в Python 3.10.Изменено в Python 3.10: удален аргумент
loop
.Устарело, начиная с Python 3.10: выдается предупреждение об устаревании, если не все ожидаемые объекты в
aws
являются объектами, подобнымиFuture
, и нет запущенного цикла событий.Изменено в Python 3.12: добавлена поддержка генераторов, выдающих задания.
import asyncio, time async def worker(delay, name): # эмитируем ожидание какого-то ответа # ответа от стороннего сервиса await asyncio.sleep(delay) # возвращаем результат return name, delay async def main(): # список аргументов для `worker()`` targets = [(0.5, 'one'), (0.8, 'two'), (0.2, 'three'), (1, 'four'), (0.5, 'five')] # создаем задачи tasks = [asyncio.create_task(worker(*target)) for target in targets] # передаем задачи в функцию `as_completed()` for future in asyncio.as_completed(tasks): # получаем результаты по готовности res = await future # выводим на печать print(f'Задача: {res[0]}; задержка: {res[1]}') if __name__ == '__main__': start = time.time() # запускаем цикл событий asyncio.run(main()) total = time.time() - start print(f'Общее время выполнения: {total:.3f} сек.') # Задача: three; задержка: 0.2 # Задача: one; задержка: 0.5 # Задача: five; задержка: 0.5 # Задача: two; задержка: 0.8 # Задача: four; задержка: 1 # Общее время выполнения: 1.001 сек.
Попробуйте в функцию передать значение таймаута, сначала 0.8 секунды - asyncio.as_completed(tasks, dalay=0.8)
, а потом 1.1 секунды и проследить поведение программы.