В этом руководстве вы узнаете о функции asyncio.wait() в Python для одновременного ожидания запуска итерации для нескольких объектов.
Что такое функция asyncio wait() в Python?
Функция asyncio.wait() выполняет итерацию объектов awaitables и блокирует их до достижения указанного условия.
Вот синтаксис функции asyncio.wait():
asyncio.wait(aws, *, timeout=None, return_when=ALL_COMPLETED)
Функция asyncio.wait() имеет следующие параметры:
- aws перебирает ожидаемые объекты, которые вы хотите запускать одновременно.
- timeout (int или float) определяет максимальное количество секунд ожидания перед возвратом результата.
- return_when указывает, когда функция должна вернуться. return_when принимает одну из констант в таблице ниже.
| Константа | Описание |
|---|---|
| FIRST_COMPLETED | Возврат, когда все ожидаемые задачи будут выполнены или отменены. |
| FIRST_EXCEPTION | Возврат, когда любое ожидаемое завершено путем создания исключения. Если ни один ожидаемый объект не вызывает исключение, FIRST_EXCEPTION эквивалентен ALL_COMPLETED. |
| ALL_COMPLETED | Возврат, когда все ожидаемые объекты будут выполнены или отменены. |
Обратите внимание, что эти константы находятся в библиотеке asyncio, поэтому вы можете ссылаться на них, например, так: asyncio.FIRST_COMPLETED.
asyncio.wait() возвращает два набора:
done, pending = await asyncio.wait(aws)
- Done — это набор ожидаемых событий, которые выполнены.
- pending — это набор ожидаемых событий.
Пример с функцией asyncio wait() в Python
В следующем примере показано, как использовать функцию asyncio.wait():
import asyncio
from asyncio import create_task
class APIError(Exception):
pass
async def call_api(message, result=100, delay=3, raise_exception=False):
print(message)
await asyncio.sleep(delay)
if raise_exception:
raise APIError
else:
return result
async def main():
task_1 = create_task(call_api('calling API 1...', result=1, delay=1))
task_2 = create_task(call_api('calling API 2...', result=2, delay=2))
task_3 = create_task(call_api('calling API 3...', result=3, delay=3))
pending =(task_1, task_2, task_3)
while pending:
done, pending = await asyncio.wait(
pending,
return_when=asyncio.FIRST_COMPLETED
)
result = done.pop().result()
print(result)
asyncio.run(main())
Как это работает.
- Сначала определите класс APIError, который расширяет класс Exception:
class APIError(Exception):
pass
- Во-вторых, определите функцию call_api(), которая имитирует асинхронную операцию:
async def call_api(message, result=100, delay=3, raise_exception=False):
print(message)
await asyncio.sleep(delay)
if raise_exception:
raise APIError
else:
return result
- В-третьих, создайте три задачи, которые обертывают сопрограммы call_api(). Каждая сопрограмма возвращает разное число:
task_1 = create_task(call_api('calling API 1...', result=1, delay=1))
task_2 = create_task(call_api('calling API 2...', result=2, delay=2))
task_3 = create_task(call_api('calling API 3...', result=3, delay=3))
pending =(task_1, task_2, task_3)
- Наконец, вызовите функцию asyncio.wait() для запуска задач внутри цикла while. Если все задачи выполнены, ожидание будет пустым и цикл while завершится. На каждой итерации мы получаем выполненную задачу из набора Done и отображаем результат:
while pending:
done, pending = await asyncio.wait(
pending,
return_when=asyncio.FIRST_COMPLETED
)
result = done.pop().result()
print(result)
