Фьючерсы

Код источника: Lib/asyncio/futures.py, Lib/asyncio/base_futures.py


Объекты Future используются для соединения низкоуровневого кода, основанного на обратных вызовах, с высокоуровневым кодом async/await.

Будущие функции

asyncio.isfuture(obj)

Возвращает True, если obj является одним из:

  • экземпляр asyncio.Future,

  • экземпляр asyncio.Task,

  • объект типа Future с атрибутом _asyncio_future_blocking.

Added in version 3.5.

asyncio.ensure_future(obj, *, loop=None)

Возвращение:

  • Аргумент obj как есть, если obj - это Future, Task или объект типа Future (isfuture() используется для теста).

  • объект Task, оборачивающий obj, если obj - это coroutine (для теста используется:func:iscoroutine); в этом случае coroutine будет запланирован ensure_future().

  • объект Task, который будет ожидать obj, если obj является ожидаемым (inspect.isawaitable() используется для теста).

Если obj не является ни одним из вышеперечисленных, возникает сообщение TypeError.

Важно

См. также функцию create_task(), которая является предпочтительным способом создания новых Задач.

Сохраните ссылку на результат этой функции, чтобы избежать исчезновения задачи в середине выполнения.

Изменено в версии 3.5.1: Функция принимает любой объект awaitable.

Не рекомендуется, начиная с версии 3.10: Предупреждение об устаревании выдается, если obj не является Future-like объектом, а loop не указан и нет запущенного цикла событий.

asyncio.wrap_future(future, *, loop=None)

Заверните объект concurrent.futures.Future в объект asyncio.Future.

Не рекомендуется, начиная с версии 3.10: Предупреждение об устаревании выдается, если future не является Future-подобным объектом, а loop не указан и нет запущенного цикла событий.

Будущий объект

class asyncio.Future(*, loop=None)

Future представляет собой конечный результат асинхронной операции. Не является потокобезопасным.

Future - это объект awaitable. Короткие программы могут ожидать объекты Future до тех пор, пока не получат результат или исключение, или пока не будут отменены. Future можно ожидать несколько раз, и результат будет одинаковым.

Обычно Futures используются для того, чтобы низкоуровневый код, основанный на обратных вызовах (например, в протоколах, реализованных с помощью asyncio transports), мог взаимодействовать с высокоуровневым кодом async/await.

Правило заключается в том, чтобы никогда не раскрывать объекты Future в пользовательских API, и рекомендуемый способ создания объекта Future - это вызов loop.create_future(). Таким образом, альтернативные реализации циклов событий смогут внедрить свои собственные оптимизированные реализации объекта Future.

Изменено в версии 3.7: Добавлена поддержка модуля contextvars.

Не рекомендуется, начиная с версии 3.10: Предупреждение об устаревании выдается, если не указан loop и нет запущенного цикла событий.

result()

Возвращает результат выполнения Future.

Если Future выполнено и результат установлен методом set_result(), возвращается значение результата.

Если Future выполнено и имеет исключение, установленное методом set_exception(), этот метод поднимает исключение.

Если будущее было отменено, этот метод вызывает исключение CancelledError.

Если результат Future еще не доступен, этот метод вызывает исключение InvalidStateError.

set_result(result)

Пометьте будущее как выполненное и установите его результат.

Вызывает ошибку InvalidStateError, если будущее уже выполнено.

set_exception(exception)

Пометьте будущее как выполненное и установите исключение.

Вызывает ошибку InvalidStateError, если будущее уже выполнено.

done()

Возвращает True, если будущее закончено.

Будущее считается выполненным, если оно было отменено или если оно имеет результат или исключение, установленное с помощью вызовов set_result() или set_exception().

cancelled()

Возвращает True, если будущее было отменено.

Метод обычно используется для проверки того, не является ли Future отмененным, прежде чем установить для него результат или исключение:

if not fut.cancelled():
    fut.set_result(42)
add_done_callback(callback, *, context=None)

Добавьте обратный вызов, который будет выполняться, когда будущее будет закончено.

Вызывается обратный вызов с объектом Future в качестве единственного аргумента.

Если на момент вызова этого метода Future уже выполнено, обратный вызов будет назначен с loop.call_soon().

Необязательный аргумент context, содержащий только ключевое слово, позволяет указать пользовательский contextvars.Context для запуска callback. Текущий контекст используется, если не указан context.

functools.partial() можно использовать для передачи параметров обратному вызову, например:

# Call 'print("Future:", fut)' when "fut" is done.
fut.add_done_callback(
    functools.partial(print, "Future:"))

Изменено в версии 3.7: Добавлен параметр контекст, который зависит только от ключевого слова. Более подробную информацию см. в разделе PEP 567.

remove_done_callback(callback)

Удалите callback из списка обратных вызовов.

Возвращает количество удаленных обратных вызовов, которое обычно равно 1, если только обратный вызов не был добавлен более одного раза.

cancel(msg=None)

Отмените будущее и запланируйте обратные вызовы.

Если будущее уже выполнено или отменено, верните False. В противном случае измените состояние будущего на отменено, запланируйте обратные вызовы и верните True.

Изменено в версии 3.9: Добавлен параметр msg.

exception()

Возвращает исключение, которое было установлено для этого Future.

Исключение (или None, если исключение не было задано) возвращается только в том случае, если Future done.

Если будущее было отменено, этот метод вызывает исключение CancelledError.

Если будущее еще не закончено, этот метод вызывает исключение InvalidStateError.

get_loop()

Возвращает цикл событий, к которому привязан объект Future.

Added in version 3.7.

Этот пример создает объект Future, создает и планирует асинхронную задачу, чтобы установить результат для Future, и ждет, пока Future не получит результат:

async def set_after(fut, delay, value):
    # Sleep for *delay* seconds.
    await asyncio.sleep(delay)

    # Set *value* as a result of *fut* Future.
    fut.set_result(value)

async def main():
    # Get the current event loop.
    loop = asyncio.get_running_loop()

    # Create a new Future object.
    fut = loop.create_future()

    # Run "set_after()" coroutine in a parallel Task.
    # We are using the low-level "loop.create_task()" API here because
    # we already have a reference to the event loop at hand.
    # Otherwise we could have just used "asyncio.create_task()".
    loop.create_task(
        set_after(fut, 1, '... world'))

    print('hello ...')

    # Wait until *fut* has a result (1 second) and print it.
    print(await fut)

asyncio.run(main())

Важно

Объект Future был разработан для имитации concurrent.futures.Future. Основные отличия включают: