# Ф’ючерси

Вихідний код: Lib/asyncio/futures.py, Lib/asyncio/base_futures.py

Об’єкти Future використовуються для з’єднання низькорівневого коду на основі зворотного виклику з високорівневим асинхронним кодом/кодом очікування.

## Майбутні функції

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 є співпрограмою (для тесту використовується `iscoroutine()`); у цьому випадку співпрограма буде запланована `ensure_future()`.

  - об’єкт `Task`, який очікуватиме на obj, якщо obj є очікуваним (`inspect.isawaitable()` використовується для тесту.)

  Якщо obj не є жодним із наведених вище, виникає `TypeError`.

  Важливо

  Дивіться також функцію `create_task()`, яка є кращим способом створення нових завдань.

  Save a reference to the result of this function, to avoid a task disappearing mid-execution.

  Змінено в версії 3.5.1: Функція приймає будь-який об’єкт awaitable.

  Застаріло починаючи з версії 3.10: Якщо obj не є Future-подібним об’єктом і loop не вказано, і цикл подій не виконується, видається попередження про застаріле.

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

  Загорніть об’єкт `concurrent.futures.Future` в об’єкт `asyncio.Future`.

  Застаріло починаючи з версії 3.10: Якщо future не є об’єктом, схожим на Future, і loop не вказано, і немає запущеного циклу подій, видається попередження про застаріння.

## Майбутній об’єкт

class asyncio.Future(*, loop=None)

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

  Future is an awaitable object. Coroutines can await on Future objects until they either have a result or an exception set, or until they are cancelled. A Future can be awaited multiple times and the result is same.

  Зазвичай ф’ючерси використовуються, щоб увімкнути низькорівневий код на основі зворотного виклику (наприклад, у протоколах, реалізованих за допомогою asyncio transports) для взаємодії з високорівневим асинхронним кодом/кодом очікування.

  Емпіричне правило полягає в тому, щоб ніколи не показувати об’єкти Future в призначених для користувача API, а рекомендований спосіб створити об’єкт Future – це викликати `loop.create_future()`. Таким чином альтернативні реалізації циклу подій можуть вводити власні оптимізовані реалізації об’єкта Future.

  Змінено в версії 3.7: Додано підтримку модуля `contextvars`.

  Застаріло починаючи з версії 3.10: Якщо loop не вказано і немає запущеного циклу подій, видається попередження про застаріле.

  result()

    Повернути результат Future.

    Якщо Future done і має результат, встановлений методом `set_result()`, повертається значення результату.

    Якщо Future done і має виняток, встановлений методом `set_exception()`, цей метод викликає виняток.

    Якщо Future було скасовано, цей метод викликає виняток `CancelledError`.

    If the Future’s result isn’t yet available, this method raises an `InvalidStateError` exception.

  set_result(result)

    Позначте майбутнє як виконане та встановіть його результат.

    Raises an `InvalidStateError` error if the Future is already done.

  set_exception(exception)

    Позначте майбутнє як готове та встановіть виняток.

    Raises an `InvalidStateError` error if the Future is already done.

  done()

    Повертає `True`, якщо Future done.

    Майбутнє вважається виконаним, якщо його було скасовано або якщо він має результат чи виняток, встановлений за допомогою викликів `set_result()` або `set_exception()`.

  cancelled()

    Повертає `True`, якщо Future було скасовано.

    Метод зазвичай використовується, щоб перевірити, чи Future не скасовано перед встановленням результату або винятку для нього:

        if not fut.cancelled():
            fut.set_result(42)

  add_done_callback(callback, *, context=None)

    Додайте зворотний виклик, який буде запущено, коли Майбутнє зроблено.

    Зворотний виклик викликається з об’єктом Future як єдиним аргументом.

    Якщо Future вже done під час виклику цього методу, зворотний виклик планується за допомогою `loop.call_soon()`.

    Необов’язковий аргумент context, що містить лише ключове слово, дозволяє вказати спеціальний `contextvars.Context` для виконання зворотного виклику. Поточний контекст використовується, якщо контексту не надано.

    `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)

    Скасувати майбутнє та запланувати зворотні виклики.

    Якщо Future вже виконано або скасовано, поверніть `False`. В іншому випадку змініть стан Future на cancelled, заплануйте зворотні виклики та поверніть `True`.

    Змінено в версії 3.9: Додано параметр msg.

  exception()

    Повертає виняток, встановлений для цього Future.

    Виняток (або `None`, якщо виключення не було встановлено) повертається, лише якщо Future done.

    Якщо Future було скасовано, цей метод викликає виняток `CancelledError`.

    Якщо Future ще не зроблено, цей метод викликає виняток `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`. Основні відмінності:

- на відміну від asyncio Futures, екземпляри `concurrent.futures.Future` не можна чекати.

- `asyncio.Future.result()` і `asyncio.Future.exception()` не приймають аргумент timeout.

- `asyncio.Future.result()` і `asyncio.Future.exception()` викликають виняток `InvalidStateError`, коли Future не виконано.

- Зворотні виклики, зареєстровані за допомогою `asyncio.Future.add_done_callback()`, не викликаються негайно. Натомість вони плануються за допомогою `loop.call_soon()`.

- asyncio Future несумісний із функціями `concurrent.futures.wait()` і `concurrent.futures.as_completed()`.

- `asyncio.Future.cancel()` accepts an optional `msg` argument, but `concurrent.futures.Future.cancel()` does not.