Giải pháp cuối cùng của bạn là cách duy nhất đúng.
Hai giải pháp khác không nên hoạt động như bạn mong đợi chúng hoạt động. Trên thực tế, điều này sẽ dẫn đến một vòng lặp vô hạn.
Điều này là do cách hoạt động của eventloop của JavaScript . Hình ảnh sau đây cho thấy một mô hình thời gian chạy JavaScript (Hình ảnh được lấy từ đây ):
Các phần có liên quan cho chúng tôi là stack
và queue
. Một thời gian chạy JavaScript xử lý các thông báo trên queue
. Mỗi tin nhắn được liên kết với một chức năng được gọi là tin nhắn được xử lý.
Đối với ngăn xếp, mỗi lệnh gọi hàm tạo một khung trên ngăn xếp chứa các đối số hàm và biến cục bộ. Nếu một chức năng gọi một chức năng khác, một khung mới sẽ được đẩy lên trên cùng của ngăn xếp. Khi một hàm trả về khung trên cùng được bật ra khỏi ngăn xếp.
Bây giờ nếu ngăn xếp trống, bộ thực thi JavaScript sẽ xử lý thông báo tiếp theo trên queue
(thư cũ nhất).
Nếu bạn sử dụng setTimeout(() => doSomething(),100)
, doSomething()
chức năng sẽ được thêm vào hàng đợi sau 100 mili giây. Đây là lý do tại sao 100 mili giây không phải là thời gian được đảm bảo mà là thời gian tối thiểu. Do đó, doSomething method
chỉ được gọi của bạn , nếu ngăn xếp trống và không có gì khác trong hàng đợi.
Nhưng khi bạn lặp lại trong một vòng lặp while và điều kiện của bạn phụ thuộc vào mã bên trong setTimeout
, bạn đã tạo một vòng lặp vô hạn vì ngăn xếp sẽ không trống và do đó this.posts.push(this.postService.next(10));
mã của bạn sẽ không bao giờ được gọi.
Đối với các triển khai RxJS, điều tương tự là đúng. Họ sử dụng lịch trình để xử lý thời gian. Có các triển khai lập lịch trình nội bộ khác nhau trong RxJS, nhưng như chúng ta có thể thấy trong các triển khai cho interval
và timer
, nếu chúng ta không chỉ định một trình lập lịch biểu thì trình mặc định là asyncScheduler. Lịch biểu asyncScheduler hoạt động với setInterval
các hoạt động như setTimeout
đã đề cập ở trên và đẩy một thông báo khác trên hàng đợi.
Tôi đã thử hai giải pháp của bạn với vòng lặp while và thực tế là giải pháp đầu tiên hoàn toàn đóng băng trình duyệt của tôi trong khi giải pháp thứ hai siêu lag nhưng có thể xuất ra thứ gì đó cho giao diện điều khiển bên trong vòng lặp while. Tôi thực sự không biết tại sao cái thứ hai lại có hiệu suất cao hơn một chút, nhưng cả hai không phải là thứ bạn thực sự muốn. Bạn đã đưa ra một giải pháp tốt và tôi hy vọng câu trả lời này có thể giúp bạn hiểu tại sao các giải pháp đầu tiên thực hiện quá tệ.