Использование функции asyncio.wait() в Python
В этом руководстве вы узнаете о функции 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)