Coroutine là một hàm tạo có thể vừa mang lại giá trị vừa chấp nhận các giá trị từ bên ngoài. Lợi ích của việc sử dụng quy trình đăng ký là chúng ta có thể tạm dừng việc thực thi một chức năng và tiếp tục lại sau. Trong trường hợp hoạt động mạng, bạn nên tạm dừng việc thực thi một chức năng trong khi chúng tôi đang chờ phản hồi. Chúng ta có thể sử dụng thời gian để chạy một số chức năng khác.
Tương lai giống như các Promise
đối tượng từ Javascript. Nó giống như một trình giữ chỗ cho một giá trị sẽ được hiện thực hóa trong tương lai. Trong trường hợp nêu trên, trong khi chờ I / O mạng, một hàm có thể cung cấp cho chúng ta một vùng chứa, một lời hứa rằng nó sẽ lấp đầy giá trị cho vùng chứa khi hoạt động hoàn tất. Chúng tôi giữ đối tượng tương lai và khi nó được hoàn thành, chúng tôi có thể gọi một phương thức trên đó để lấy kết quả thực tế.
Trả lời trực tiếp: Bạn không cần ensure_future
nếu bạn không cần kết quả. Chúng tốt nếu bạn cần kết quả hoặc truy xuất các trường hợp ngoại lệ xảy ra.
Tín dụng bổ sung: Tôi sẽ chọn run_in_executor
và chuyển một Executor
phiên bản để kiểm soát số lượng công nhân tối đa.
Giải thích và Mã mẫu
Trong ví dụ đầu tiên, bạn đang sử dụng coroutines. Các wait
chức năng phải mất một loạt các coroutines và kết hợp chúng lại với nhau. Vì vậy, wait()
kết thúc khi tất cả các coroutines đã hết (hoàn thành / kết thúc trả về tất cả các giá trị).
loop = get_event_loop() #
loop.run_until_complete(wait(coros))
Các run_until_complete
phương pháp sẽ đảm bảo rằng các vòng lặp là còn sống cho đến khi thực hiện xong. Vui lòng lưu ý cách bạn không nhận được kết quả của việc thực thi không đồng bộ trong trường hợp này.
Trong ví dụ thứ hai, bạn đang sử dụng ensure_future
hàm để bọc một quy trình đăng quang và trả về một Task
đối tượng là một loại Future
. Quy trình đăng quang được lên lịch thực hiện trong vòng lặp sự kiện chính khi bạn gọi ensure_future
. Đối tượng tương lai / nhiệm vụ được trả về chưa có giá trị nhưng theo thời gian, khi các hoạt động mạng kết thúc, đối tượng tương lai sẽ giữ kết quả của hoạt động.
from asyncio import ensure_future
futures = []
for i in range(5):
futures.append(ensure_future(foo(i)))
loop = get_event_loop()
loop.run_until_complete(wait(futures))
Vì vậy, trong ví dụ này, chúng tôi đang làm điều tương tự ngoại trừ chúng tôi đang sử dụng tương lai thay vì chỉ sử dụng coroutines.
Hãy xem một ví dụ về cách sử dụng asyncio / coroutines / futures:
import asyncio
async def slow_operation():
await asyncio.sleep(1)
return 'Future is done!'
def got_result(future):
print(future.result())
# We have result, so let's stop
loop.stop()
loop = asyncio.get_event_loop()
task = loop.create_task(slow_operation())
task.add_done_callback(got_result)
# We run forever
loop.run_forever()
Ở đây, chúng tôi đã sử dụng create_task
phương thức trên loop
đối tượng. ensure_future
sẽ lên lịch nhiệm vụ trong vòng lặp sự kiện chính. Phương pháp này cho phép chúng tôi lập lịch trình đăng ký trên một vòng lặp mà chúng tôi chọn.
Chúng ta cũng thấy khái niệm thêm một cuộc gọi lại bằng cách sử dụng add_done_callback
phương thức trên đối tượng tác vụ.
A Task
là done
khi chương trình đăng quang trả về một giá trị, tăng một ngoại lệ hoặc bị hủy bỏ. Có những phương pháp để kiểm tra những sự cố này.
Tôi đã viết một số bài đăng trên blog về các chủ đề này có thể giúp ích:
Tất nhiên, bạn có thể tìm thêm chi tiết trên hướng dẫn chính thức: https://docs.python.org/3/library/asyncio.html
ensure_future()
không? Và nếu tôi cần kết quả, tôi có thể sử dụngrun_until_complete(gather(coros))
không?