Vấn đề bạn mô tả là hai lần.
- Chương trình bạn đang viết nên hoạt động không đồng bộ một cách tổng thể khi nhìn từ bên ngoài .
- Nó không nên được hiển thị tại trang web cuộc gọi cho dù một cuộc gọi chức năng có khả năng từ bỏ quyền kiểm soát hay không.
Có một vài cách để đạt được điều này, nhưng về cơ bản, họ đã đun sôi để
- có nhiều luồng (ở một mức độ trừu tượng)
- có nhiều loại chức năng ở cấp độ ngôn ngữ, tất cả đều được gọi như thế này
foo(4, 7, bar, quux)
.
Đối với (1), tôi kết hợp với nhau để chạy và chạy nhiều tiến trình, sinh ra nhiều luồng nhân và triển khai luồng xanh lập lịch trình xử lý các luồng mức thời gian chạy ngôn ngữ lên các luồng nhân. Từ quan điểm của vấn đề, họ là như nhau. Trong thế giới này, không có chức năng nào từ bỏ hoặc mất quyền kiểm soát từ quan điểm của chủ đề . Bản thân luồng đôi khi không có quyền kiểm soát và đôi khi không chạy nhưng bạn không từ bỏ quyền kiểm soát chủ đề của chính mình trong thế giới này. Một hệ thống phù hợp với mô hình này có thể có hoặc không có khả năng sinh ra các luồng mới hoặc tham gia vào các luồng hiện có. Một hệ thống phù hợp với mô hình này có thể có hoặc không có khả năng sao chép một luồng như Unix fork
.
(2) là thú vị. Để thực hiện công lý, chúng ta cần nói về các hình thức giới thiệu và loại bỏ.
Tôi sẽ chỉ ra lý do tại sao await
không thể thêm vào một ngôn ngữ như Javascript theo cách tương thích ngược. Ý tưởng cơ bản là bằng cách đưa ra những lời hứa với người dùng và có sự phân biệt giữa bối cảnh đồng bộ và không đồng bộ, Javascript đã rò rỉ một chi tiết triển khai ngăn chặn xử lý thống nhất các chức năng đồng bộ và không đồng bộ. Ngoài ra còn có một thực tế là bạn không thể await
hứa hẹn bên ngoài cơ thể chức năng không đồng bộ. Các lựa chọn thiết kế này không tương thích với "làm cho tính không đồng bộ trở nên vô hình đối với người gọi".
Bạn có thể giới thiệu một chức năng đồng bộ bằng cách sử dụng lambda và loại bỏ nó bằng một lệnh gọi hàm.
Giới thiệu chức năng đồng bộ:
((x) => {return x + x;})
Loại bỏ chức năng đồng bộ:
f(4)
((x) => {return x + x;})(4)
Bạn có thể đối chiếu điều này với việc giới thiệu và loại bỏ chức năng không đồng bộ.
Giới thiệu chức năng không đồng bộ
(async (x) => {return x + x;})
Loại bỏ chức năng không đồng bộ (lưu ý: chỉ hợp lệ trong một async
chức năng)
await (async (x) => {return x + x;})(4)
Vấn đề cơ bản ở đây là một hàm không đồng bộ cũng là một hàm đồng bộ tạo ra một đối tượng hứa .
Đây là một ví dụ về cách gọi một hàm không đồng bộ một cách đồng bộ trong thay thế node.js.
> (async (x) => {return x + x;})(4)
Promise { 8 }
Theo giả thuyết, bạn có thể có một ngôn ngữ, thậm chí là một ngôn ngữ được gõ động, trong đó sự khác biệt giữa các cuộc gọi chức năng không đồng bộ và đồng bộ không thể nhìn thấy tại trang web cuộc gọi và có thể không hiển thị tại trang web định nghĩa.
Có thể sử dụng một ngôn ngữ như thế và hạ thấp nó xuống Javascript, bạn chỉ cần thực hiện một cách hiệu quả tất cả các chức năng không đồng bộ.