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