Использование функции 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)
Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *