Ф’ючерси¶
Вихідний код: 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 optionalmsg
argument, butconcurrent.futures.Future.cancel()
does not.