Futures?
源代碼: Lib/asyncio/futures.py, Lib/asyncio/base_futures.py
Future 對象用來鏈接 底層回調(diào)式代碼 和高層異步/等待式代碼。
Future 函數(shù)?
- asyncio.isfuture(obj)?
如果 obj 為下面任意對象,返回
True
:一個
asyncio.Future
類的實例,一個
asyncio.Task
類的實例,帶有
_asyncio_future_blocking
屬性的類似 Future 的對象。
3.5 新版功能.
- asyncio.ensure_future(obj, *, loop=None)?
返回:
obj 參數(shù)會是保持原樣,如果 obj 是
Future
、Task
或 類似 Future 的對象(isfuture()
用于測試。)封裝了 obj 的
Task
對象,如果 obj 是一個協(xié)程 (使用iscoroutine()
進行檢測);在此情況下該協(xié)程將通過ensure_future()
加入執(zhí)行計劃。等待 obj 的
Task
對象,如果 obj 是一個可等待對象(inspect.isawaitable()
用于測試)
如果 obj 不是上述對象會引發(fā)一個
TypeError
異常。重要
查看
create_task()
函數(shù),它是創(chuàng)建新任務(wù)的首選途徑。Save a reference to the result of this function, to avoid a task disappearing mid execution.
在 3.5.1 版更改: 這個函數(shù)接受任意 awaitable 對象。
3.10 版后已移除: 如果 obj 不是 Future 類對象同時未指定 loop 并且沒有正在運行的事件循環(huán)則會發(fā)出棄用警告。
- asyncio.wrap_future(future, *, loop=None)?
將一個
concurrent.futures.Future
對象封裝到asyncio.Future
對象中。3.10 版后已移除: 如果 future 不是 Future 類對象同時未指定 loop 并且沒有正在運行的事件循環(huán)則會發(fā)出棄用警告。
Future 對象?
- class asyncio.Future(*, loop=None)?
一個 Future 代表一個異步運算的最終結(jié)果。線程不安全。
Future 是一個 awaitable 對象。協(xié)程可以等待 Future 對象直到它們有結(jié)果或異常集合或被取消。
通常 Future 用于支持底層回調(diào)式代碼(例如在協(xié)議實現(xiàn)中使用asyncio transports) 與高層異步/等待式代碼交互。
經(jīng)驗告訴我們永遠不要面向用戶的接口暴露 Future 對象,同時建議使用
loop.create_future()
來創(chuàng)建 Future 對象。這種方法可以讓 Future 對象使用其它的事件循環(huán)實現(xiàn),它可以注入自己的優(yōu)化實現(xiàn)。在 3.7 版更改: 加入對
contextvars
模塊的支持。3.10 版后已移除: 如果未指定 loop 并且沒有正在運行的事件循環(huán)則會發(fā)出棄用警告。
- result()?
返回 Future 的結(jié)果。
如果 Future 狀態(tài)為 完成 ,并由
set_result()
方法設(shè)置一個結(jié)果,則返回這個結(jié)果。如果 Future 狀態(tài)為 完成 ,并由
set_exception()
方法設(shè)置一個異常,那么這個方法會引發(fā)異常。如果 Future 已 取消,方法會引發(fā)一個
CancelledError
異常。如果 Future 的結(jié)果還不可用,此方法會引發(fā)一個
InvalidStateError
異常。
- set_result(result)?
將 Future 標記為 完成 并設(shè)置結(jié)果。
如果 Future 已經(jīng) 完成 則拋出一個
InvalidStateError
錯誤。
- set_exception(exception)?
將 Future 標記為 完成 并設(shè)置一個異常。
如果 Future 已經(jīng) 完成 則拋出一個
InvalidStateError
錯誤。
- done()?
如果 Future 為已 完成 則返回
True
。如果 Future 為 取消 或調(diào)用
set_result()
設(shè)置了結(jié)果或調(diào)用set_exception()
設(shè)置了異常,那么它就是 完成 。
- cancelled()?
如果 Future 已 取消 則返回
True
這個方法通常在設(shè)置結(jié)果或異常前用來檢查 Future 是否已 取消 。
if not fut.cancelled(): fut.set_result(42)
- add_done_callback(callback, *, context=None)?
添加一個在 Future 完成 時運行的回調(diào)函數(shù)。
調(diào)用 callback 時,F(xiàn)uture 對象是它的唯一參數(shù)。
如果調(diào)用這個方法時 Future 已經(jīng) 完成,回調(diào)函數(shù)會被
loop.call_soon()
調(diào)度。可選鍵值類的參數(shù) context 允許 callback 運行在一個指定的自定義
contextvars.Context
對象中。如果沒有提供 context ,則使用當前上下文。可以用
functools.partial()
給回調(diào)函數(shù)傳遞參數(shù),例如:# Call 'print("Future:", fut)' when "fut" is done. fut.add_done_callback( functools.partial(print, "Future:"))
在 3.7 版更改: 加入鍵值類形參 context。請參閱 PEP 567 查看更多細節(jié)。
- remove_done_callback(callback)?
從回調(diào)列表中移除 callback 。
返回被移除的回調(diào)函數(shù)的數(shù)量,通常為1,除非一個回調(diào)函數(shù)被添加多次。
- cancel(msg=None)?
取消 Future 并調(diào)度回調(diào)函數(shù)。
如果 Future 已經(jīng) 完成 或 取消 ,返回
False
。否則將 Future 狀態(tài)改為 取消 并在調(diào)度回調(diào)函數(shù)后返回True
。在 3.9 版更改: Added the msg parameter.
Deprecated since version 3.11, will be removed in version 3.14: msg parameter is ambiguous when multiple
cancel()
are called with different cancellation messages. The argument will be removed.
- exception()?
返回 Future 已設(shè)置的異常。
只有 Future 在 完成 時才返回異常(或者
None
,如果沒有設(shè)置異常)。如果 Future 已 取消,方法會引發(fā)一個
CancelledError
異常。如果 Future 還沒 完成 ,這個方法會引發(fā)一個
InvalidStateError
異常。
- get_loop()?
返回 Future 對象已綁定的事件循環(huán)。
3.7 新版功能.
這個例子創(chuàng)建一個 Future 對象,創(chuàng)建和調(diào)度一個異步任務(wù)去設(shè)置 Future 結(jié)果,然后等待其結(jié)果:
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 的 Future 不同,
concurrent.futures.Future
實例不是可等待對象。asyncio.Future.result()
和asyncio.Future.exception()
不接受 timeout 參數(shù)。Future 沒有 完成 時
asyncio.Future.result()
和asyncio.Future.exception()
拋出一個InvalidStateError
異常。使用
asyncio.Future.add_done_callback()
注冊的回調(diào)函數(shù)不會立即調(diào)用,而是被loop.call_soon()
調(diào)度。asyncio Future 不能兼容
concurrent.futures.wait()
和concurrent.futures.as_completed()
函數(shù)。asyncio.Future.cancel()
接受一個可選的msg
參數(shù),但concurrent.futures.cancel()
無此參數(shù)。Deprecated since version 3.11, will be removed in version 3.14: msg parameter is ambiguous when multiple
cancel()
are called with different cancellation messages. The argument will be removed.