Câu hỏi này liên quan đến ngôn ngữ C #, nhưng tôi hy vọng nó sẽ bao gồm các ngôn ngữ khác như Java hoặc TypeScript.
Microsoft khuyến nghị thực hành tốt nhất về việc sử dụng các cuộc gọi không đồng bộ trong .NET. Trong số các khuyến nghị này, chúng ta hãy chọn hai:
- thay đổi chữ ký của các phương thức async để chúng trả về Nhiệm vụ hoặc Tác vụ <> (trong TypeScript, đó sẽ là một Lời hứa <>)
- thay đổi tên của các phương thức async để kết thúc bằng xxxAsync ()
Bây giờ, khi thay thế một thành phần đồng bộ, cấp thấp bằng một thành phần không đồng bộ, điều này sẽ tác động đến toàn bộ ứng dụng. Vì async / await chỉ có tác động tích cực nếu được sử dụng "hết cách", điều đó có nghĩa là tên chữ ký và phương thức của mỗi lớp trong ứng dụng phải được thay đổi.
Một kiến trúc tốt thường liên quan đến việc đặt trừu tượng giữa mỗi lớp, sao cho việc thay thế các thành phần cấp thấp bằng các thành phần khác không được nhìn thấy bởi các thành phần cấp trên. Trong C #, trừu tượng có dạng giao diện. Nếu chúng tôi giới thiệu một thành phần mới, mức độ thấp, không đồng bộ, mỗi giao diện trong ngăn xếp cuộc gọi cần phải được sửa đổi hoặc thay thế bằng một giao diện mới. Cách giải quyết vấn đề (không đồng bộ hoặc đồng bộ hóa) trong lớp triển khai không bị ẩn (trừu tượng hóa) đối với người gọi nữa. Người gọi phải biết đó là đồng bộ hóa hay không đồng bộ.
Không đồng bộ / chờ đợi các thực tiễn tốt nhất mâu thuẫn với các nguyên tắc "kiến trúc tốt"?
Điều đó có nghĩa là mỗi giao diện (giả sử IEnumerable, IDataAccessLayer) cần đối tác không đồng bộ của chúng (IAsyncEnumerable, IAsyncDataAccessLayer) sao cho chúng có thể được thay thế trong ngăn xếp khi chuyển sang phụ thuộc async?
Nếu chúng ta đẩy vấn đề đi xa hơn một chút, sẽ không đơn giản hơn khi giả sử mọi phương thức là không đồng bộ (để trả về Tác vụ <> hoặc Lời hứa <>) và cho các phương thức để đồng bộ hóa các cuộc gọi không đồng bộ khi chúng không thực sự không đồng bộ? Đây có phải là một cái gì đó được mong đợi từ các ngôn ngữ lập trình trong tương lai?
CancellationToken
và các phương thức có thể muốn cung cấp mặc định). Loại bỏ các phương thức đồng bộ hóa hiện có (và chủ động phá vỡ tất cả mã) là một cách không rõ ràng.