Футуры

Source code: Lib/asyncio/futures.py, Lib/asyncio/base_futures.py


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

Функции футуры

asyncio.isfuture(obj)

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

  • сущностью asyncio.Future,
  • сущностью asyncio.Task,
  • футоподобный объект с атрибутом _asyncio_future_blocking.

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

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

Возвращает:

  • obj аргумент, если obj является Future, Task или объект, похожий на Future (isfuture() используется для тестов.)
  • Task обёртка для obj объекта, если obj является корутином (iscoroutine() используется для тестов); в этом случае корутин будет запланирован ensure_future().
  • объект Task, который был бы await obj, если obj - awaitable (inspect.isawaitable() - используется для тестов.)

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

Важно

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

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

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

Перенос объекта concurrent.futures.Future в объект asyncio.Future.

Объект футуры

class asyncio.Future(*, loop=None)

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

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

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

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

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

result()

Возвращает результат футуры.

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

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

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

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

set_result(result)

Отмечает Future как выполненная и задаёт её результат.

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

set_exception(exception)

Маркирует Future как выполненная и определяет исключение.

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

done()

Возвращение True, если Future выполнена.

Future выполнена, если оно было отменено или имеет результат или набор исключений с 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 для запуска колбэка. Используется текущий контекст, если context не передан.

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

# Вызов 'print("Future:", fut)' когда "fut" выполнен.
fut.add_done_callback(
    functools.partial(print, "Future:"))

Изменено в версии 3.7: Добавлен ключевой параметр context. Дополнительные сведения см. в разделе PEP 567.

remove_done_callback(callback)

Удалить callback из списка колбэков.

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

cancel()

Отменена Future и запланированных колбэков.

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

exception()

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

Возвращается исключение (или None, если оно не было установлено), только если футура выполнена.

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

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

get_loop()

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

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

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

async def set_after(fut, delay, value):
    # Спать *delay* секунд.
    await asyncio.sleep(delay)

    # Установить *value* как рузультат *fut* Future.
    fut.set_result(value)

async def main():
    # Получить текущий событийный цикл.
    loop = asyncio.get_running_loop()

    # Создание объекта Future.
    fut = loop.create_future()

    # Запуск "set_after()" корутину в параллельной Task.
    # Мы используем низкоуровневое "loop.create_task()" API потому что
    # у нас уже есть ссылка на событийный цикл под рукой.
    # В противном случае мы могли бы просто использовать "asyncio.create_task()".
    loop.create_task(
        set_after(fut, 1, '... world'))

    print('hello ...')

    # Подождать, пока *fut* не получит результат (1 секунда) и распечатать его.
    print(await fut)

asyncio.run(main())

Важно

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