import asyncio done, pending = asyncio.wait(aws, *, loop=None, timeout=None, return_when=ALL_COMPLETED)
aws
- множество объектов ожидания,loop=None
- параметры цикла (удален с версии Python 3.10),timeout=None
- максимальным количеством секунд ожидания,return_when=ALL_COMPLETED
- когда функция должна возвратить результат.asyncio.wait
:Функция wait()
модуля asyncio
одновременно запускает awaitable-объекты (преимущественно задачи Task
) из переданного множества aws
и производит блокировку выполнения программы до выполнения условия, указанного в аргументе return_when
.
Возвращает кортеж из двух множеств Task
/Future
в виде (done, pending)
.
# псевдокод done, pending = await asyncio.wait(aws)
Аргумент timeout
(float
или int
) в секундах, если он указан, можно использовать для управления временем ожидания результатов задач, из множества aws
, прежде чем приостановить не выполненные задачи.
Обратите внимание, что функция asyncio.wait()
не вызывает исключение asyncio.TimeoutError
. Задачи, которые не успели выполнится по истечении timeout
, приостанавливают свое выполнение и возвращаются во втором множестве pending
. В последствии, можно возобновить выполнение приостановленных задач.
Аргумент return_when
указывает, когда функция asyncio.wait()
должна возвратить результат. Это должна быть одна из следующих констант:
Константа | Описание |
asyncio.FIRST_COMPLETED | Функция возвратит результат, когда любой из Future завершится или был отменен. |
asyncio.FIRST_EXCEPTION | Функция возвратит результат, когда любой из Future завершится созданием исключения. Если никакое Future не вызывает исключения, то эта константа эквивалентна asyncio.ALL_COMPLETED . |
asyncio.ALL_COMPLETED | Функция возвратит результат, когда все Future завершатся или будут отменены. |
В отличие от функции asyncio.wait_for()
, asyncio.wait()
не отменяет, а приостанавливает задачи при наступлении таймаута.
Изменено в Python 3.8: Прямая передача сопрограмм в функцию
asyncio.wait()
не рекомендуется, так как это приводит к запутанному поведению. Если какой-либо объект, ожидающий результатов в*aws
является сопрограммой, то он автоматически назначается как задачаTask
.Устарело с Python 3.8: аргумент
loop
устарел и будет удален в Python 3.10Изменено в Python 3.10: удален аргумент
loop
.Изменено в Python 3.11: запрещена прямая передача объектов сопрограммы в
asyncio.wait()
.Изменено в Python 3.12: добавлена поддержка генераторов, выдающих задания.
Функция asyncio.wait_for()
поддерживает приостановку выполнения задач, после получения результата задачи, которая вернула их первой или после указанного таймаута, что обеспечивает более низкий уровень точности операций:
import asyncio, random async def worker(tag): """Основная сопрограмма""" print('Run:', tag) # эмитируем ожидание ответа сервера случайным # образом при помощи модуля `random` await asyncio.sleep(random.uniform(0.5, 5)) print('Done:', tag) return tag async def main(): """Точка входа в программу""" # создаем и планируем асинхронный запуск задач tasks = [asyncio.create_task(worker(tag)) for tag in range(1, 8)] # запускаем созданные задачи до получения любого первого результата done, pending1 = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED) print("Приостановка задач, после получения первого результата:") for future in done: res = future.result() print(f' Результаты задачи №{res} получены.') print("Кол-во приостановленных задач:", len(pending1), '\n') # запускаем приостановленные задачи с таймаутом в 2 сек done, pending2 = await asyncio.wait(pending1, timeout=2) print("Дальнейшие результаты после таймаута в 2 сек:") for future in done: res = future.result() print(f' Результаты задачи №{res} получены.') print("Кол-во остановленных задач после 2 сек. работы:", len(pending2), '\n') done, _ = await asyncio.wait(pending2) print("Получаем оставшиеся результаты:") for future in done: res = future.result() print(f'Результаты задачи №{res} получены.') if __name__ == "__main__": # запускаем цикл событий. asyncio.run(main()) # Run: 1 # Run: 4 # Run: 5 # Run: 3 # Run: 6 # Run: 2 # Run: 7 # Done: 4 # Приостановка задач, после получения первого результата: # Результаты задачи №4 получены. # Кол-во приостановленных задач: 6 # Done: 7 # Done: 6 # Done: 1 # Done: 5 # Дальнейшие результаты после таймаута в 2 сек: # Результаты задачи №1 получены. # Результаты задачи №7 получены. # Результаты задачи №5 получены. # Результаты задачи №6 получены. # Кол-во остановленных задач после 2 сек. работы: 2 # Done: 2 # Done: 3 # Получаем оставшиеся результаты: # Результаты задачи №2 получены. # Результаты задачи №3 получены.