Hợp đồng tương lai

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


Các đối tượng Future được sử dụng để kết nối low-level callback-based code với mã async/await cấp cao.

Chức năng tương lai

asyncio.isfuture(obj)

Trả về True nếu obj là một trong:

  • một phiên bản của asyncio.Future,

  • một phiên bản của asyncio.Task,

  • một đối tượng giống như Tương lai với thuộc tính _asyncio_future_blocking.

Added in version 3.5.

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

Trở lại:

  • Đối số obj như hiện tại, nếu objFuture, Task hoặc một đối tượng giống Tương lai (isfuture() được sử dụng để kiểm tra.)

  • một đối tượng Task bao bọc obj, nếu obj là một coroutine (iscoroutine() được sử dụng để kiểm tra); trong trường hợp này, coroutine sẽ được lên lịch bởi ensure_future().

  • một đối tượng Task sẽ chờ trên obj, nếu obj là một đối tượng có thể chờ đợi (inspect.isawaitable() được sử dụng để kiểm tra.)

Nếu obj không thuộc loại nào ở trên thì TypeError sẽ được nâng lên.

Quan trọng

Lưu tham chiếu đến kết quả của hàm này để tránh tác vụ biến mất khi đang thực thi.

Xem thêm hàm create_task() là cách ưa thích để tạo tác vụ mới hoặc sử dụng asyncio.TaskGroup để giữ tham chiếu đến tác vụ nội bộ.

Thay đổi trong phiên bản 3.5.1: Hàm này chấp nhận bất kỳ đối tượng awaitable nào.

Sắp loại bỏ từ phiên bản 3.10: Cảnh báo không dùng nữa được đưa ra nếu obj không phải là đối tượng giống Tương lai và loop không được chỉ định cũng như không có vòng lặp sự kiện đang chạy.

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

Bao bọc một đối tượng concurrent.futures.Future trong một đối tượng asyncio.Future.

Sắp loại bỏ từ phiên bản 3.10: Cảnh báo không dùng nữa được đưa ra nếu future không phải là đối tượng giống Tương lai và loop không được chỉ định cũng như không có vòng lặp sự kiện đang chạy.

Đối tượng tương lai

class asyncio.Future(*, loop=None)

Tương lai đại diện cho kết quả cuối cùng của hoạt động không đồng bộ. Không an toàn chủ đề.

Tương lai là một đối tượng awaitable. Các coroutine có thể chờ đợi trên các đối tượng Tương lai cho đến khi chúng có kết quả hoặc tập hợp ngoại lệ hoặc cho đến khi chúng bị hủy. Một Tương lai có thể được chờ đợi nhiều lần và kết quả đều giống nhau.

Thông thường, Hợp đồng tương lai được sử dụng để kích hoạt mã dựa trên lệnh gọi lại cấp thấp (ví dụ: trong các giao thức được triển khai bằng asyncio transports) để tương tác với mã async/await cấp cao.

Nguyên tắc chung là không bao giờ hiển thị các đối tượng Tương lai trong các API giao diện người dùng và cách được khuyến nghị để tạo đối tượng Tương lai là gọi loop.create_future(). Bằng cách này, việc triển khai vòng lặp sự kiện thay thế có thể đưa vào các triển khai được tối ưu hóa của riêng chúng đối với đối tượng Tương lai.

Thay đổi trong phiên bản 3.7: Đã thêm hỗ trợ cho mô-đun contextvars.

Sắp loại bỏ từ phiên bản 3.10: Cảnh báo không dùng nữa được phát ra nếu loop không được chỉ định và không có vòng lặp sự kiện đang chạy.

result()

Trả về kết quả của Tương lai.

Nếu Tương lai là done và có kết quả được đặt theo phương thức set_result() thì giá trị kết quả sẽ được trả về.

Nếu Tương lai là done và có một ngoại lệ được đặt bởi phương thức set_exception() thì phương thức này sẽ đưa ra ngoại lệ.

Nếu Tương lai là cancelled, phương pháp này sẽ đưa ra một ngoại lệ CancelledError.

Nếu kết quả của Tương lai chưa có, phương pháp này sẽ đưa ra ngoại lệ InvalidStateError.

set_result(result)

Đánh dấu Tương lai là done và đặt kết quả của nó.

Phát sinh lỗi InvalidStateError nếu Tương lai đã là done.

set_exception(exception)

Đánh dấu Tương lai là done và đặt một ngoại lệ.

Phát sinh lỗi InvalidStateError nếu Tương lai đã là done.

done()

Trả về True nếu Tương lai là done.

Tương lai là done nếu nó là cancelled hoặc nếu nó có kết quả hoặc ngoại lệ được đặt với các lệnh gọi set_result() hoặc set_exception().

cancelled()

Trả về True nếu Tương lai là cancelled.

Phương thức này thường được sử dụng để kiểm tra xem Tương lai có phải là cancelled hay không trước khi đặt kết quả hoặc ngoại lệ cho nó

nếu không fut.cancelled():
    fut.set_result(42)
add_done_callback(callback, *, context=None)

Thêm lệnh gọi lại để chạy khi Tương lai là done.

callback được gọi với đối tượng Future làm đối số duy nhất.

Nếu Tương lai đã là done khi phương thức này được gọi thì cuộc gọi lại sẽ được lên lịch với loop.call_soon().

Đối số context chỉ có từ khóa tùy chọn cho phép chỉ định một contextvars.Context tùy chỉnh để callback chạy vào. Ngữ cảnh hiện tại được sử dụng khi không cung cấp context.

functools.partial() có thể được sử dụng để truyền tham số cho lệnh gọi lại, ví dụ::

# Call 'print("Tương lai:", fut)' khi "fut" hoàn tất.
fut.add_done_callback(
    functools.partial(print, "Tương lai:"))

Thay đổi trong phiên bản 3.7: Tham số chỉ từ khóa context đã được thêm vào. Xem PEP 567 để biết thêm chi tiết.

remove_done_callback(callback)

Xóa callback khỏi danh sách gọi lại.

Trả về số lượng lệnh gọi lại đã bị loại bỏ, thường là 1, trừ khi một lệnh gọi lại được thêm nhiều lần.

cancel(msg=None)

Hủy bỏ Tương lai và lên lịch gọi lại.

Nếu Tương lai đã là done hoặc cancelled, hãy trả về False. Nếu không, hãy thay đổi trạng thái của Tương lai thành cancelled, lên lịch gọi lại và trả về True.

Đối số chuỗi tùy chọn msg được chuyển làm đối số cho ngoại lệ CancelledError được đưa ra khi chờ đợi Tương lai bị hủy.

Thay đổi trong phiên bản 3.9: Đã thêm tham số msg.

exception()

Trả về ngoại lệ đã được đặt trên Tương lai này.

Ngoại lệ (hoặc None nếu không có ngoại lệ nào được đặt) chỉ được trả về nếu Tương lai là done.

Nếu Tương lai là cancelled, phương pháp này sẽ đưa ra một ngoại lệ CancelledError.

Nếu Tương lai chưa phải là done, phương pháp này sẽ đưa ra một ngoại lệ InvalidStateError.

get_loop()

Trả về vòng lặp sự kiện mà đối tượng Future bị ràng buộc.

Added in version 3.7.

Ví dụ này tạo một đối tượng Tương lai, tạo và lên lịch một Tác vụ không đồng bộ để đặt kết quả cho Tương lai và đợi cho đến khi Tương lai có kết quả:

async def set_after(fut, delay, value):
    # Sleep trong *delay* giây.
    đang chờ asyncio.sleep(delay)

    # Set *value* là kết quả của *fut* Tương lai.
    fut.set_result(giá trị)

async def main():
    # Get vòng lặp sự kiện hiện tại.
    vòng lặp = asyncio.get_running_loop()

    # Create một đối tượng Tương lai mới.
    fut = loop.create_future()

    coroutine # Run "set_after()" trong một Tác vụ song song.
    # We đang sử dụng API "loop.create_task()" cấp thấp ở đây vì
    # we đã có sẵn một tham chiếu đến vòng lặp sự kiện.
    # Otherwise chúng ta có thể vừa sử dụng "asyncio.create_task()".
    loop.create_task(
        set_after(fut, 1, '... thế giới'))

    in('xin chào ...')

    # Wait cho đến khi *fut* có kết quả (1 giây) rồi in ra.
    in (chờ trong tương lai)

asyncio.run(chính())

Quan trọng

Đối tượng Tương lai được thiết kế để bắt chước concurrent.futures.Future. Sự khác biệt chính bao gồm: