Фьючерсы

Исходный код: 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.

Добавлено в версии 3.5.

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

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

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

  • объект Task, оборачивающий obj, если obj является coroutine (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 до тех пор, пока не будет получен результат или не будет установлено исключение, или пока они не будут отменены.

Обычно 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, если Future уже выполнено.

set_exception(exception)

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

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

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. Текущий контекст используется, если не указан контекст.

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

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

Изменено в версии 3.7: Добавлен параметр context только для ключевого слова. См. раздел 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.

Добавлено в версии 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. Основные отличия включают:

Вернуться на верх