Tìm kiếm trang web

javascript - Quá trình Async có hoàn thành như mong đợi ngay cả khi component bị hủy không


Tôi có một cửa sổ bật lên (modal), khi người dùng nhấn nút gửi trong modal, nó sẽ vào cơ sở dữ liệu của tôi và lưu một số dữ liệu ở đó. Modal sẽ đóng sau đó. Tuy nhiên, vì đây là modal, người dùng có thể đóng nó bằng nút ESC. Vì vậy tôi muốn đảm bảo rằng ngay cả khi người dùng nhấn ESC, quá trình async vẫn hoàn thành mà không bị gián đoạn giữa chừng.

Ví dụ.

// from my modal component
onSubmit() {
    this.databaseService.saveToDatabase(data)
        .first()
        .subscribe(result => {
            console.log('complete')
            closeModal();
        }, error => {
            console.log(error)
        })
}

ngOnDestroy() {
    console.log('modal Desstroyed')
}

Đối với ví dụ trên, nếu tôi nhấn esc ngay khi nhấn submit, tôi thấy từ bảng điều khiển

modal Destroyed

complete

Điều này gợi ý rằng cuộc gọi bất đồng bộ của tôi kết thúc như mong đợi, điều này là tốt. Tuy nhiên, tôi thấy điều đó thật kỳ lạ..... tại sao Angular 2 không giữ component lại cho đến khi quá trình bất đồng bộ hoàn tất. Làm sao hàm onSubmit của tôi có thể kết thúc ngay cả khi component đã bị hủy (giả sử điều đó xảy ra khi ngOnDestroy() được gọi). Trong một ngôn ngữ khác như Swift, view controller sẽ không bị hủy trừ khi toàn bộ quá trình hoàn tất (Trừ khi bạn chỉ định nó bị hủy bất kể).

Một ví dụ khác mà tôi chưa thử... sẽ xảy ra chuyện gì nếu cuộc gọi async kéo dài hơn nhiều như sau. Liệu tôi có vẫn đến được 'giai đoạn 2 hoàn tất' nếu tôi đóng modal ngay khi nhấn nút gửi

// from my modal component
onSubmit() {
    this.databaseService.saveToDatabase(data)
        .first()
        .subscribe(result => {
            console.log('complete 1st stage')
            this.databaseService.saveToDatabase(reult)
                .first()
                .subscribe(result => {
                    console.log('2nd stage complete')
                    closeModal();
                })
        })
}

Câu trả lời #1

Tôi sẽ không nói về tính không đồng bộ của JS vì chủ đề này đã được đề cập khắp Stack Overflow và nhiều trang hướng dẫn khác, v.v. Tôi chỉ nói về Observables và quản lý đăng ký.

Điều đầu tiên cần biết là "nó phụ thuộc". Nó phụ thuộc vào cách bạn tạo Observable của mình và cách bạn quản lý đăng ký của mình.

khi bạn tạo một Observable với Observable.create, bạn xác định những gì sẽ làm khi bạn hủy đăng ký. Trong ví dụ này, khoảng thời gian sẽ dừng lại khi bạn hủy đăng ký :

let foo = Observable.create((observer)=>{
  // this is called when an observer subscribe to this Observable
  let interval = setInterval(()=>{
    observer.next("foo");
  });
  // returns what to do on unsubscribe...
  return ()=>{
    clearInterval(interval);
  }
});
let sub = foo.subscribe(data=>console.log(data));
window.setTimeout(()=>sub.unsubscribe(),1000); // passed 1000ms, unsubscribe and cancel the interval...

Ví dụ, với dịch vụ Http của Angular, một yêu cầu http sẽ bị hủy khi bạn hủy đăng ký nó.

Trong khi bạn không hủy đăng ký khỏi Observable của mình và nó không hoàn thành, nó vẫn đang chạy, bất kể component có bị hủy hay không.

Lưu ý rằng thực hành tốt là tránh nhiều đăng ký, vì khi bạn quản lý các đăng ký của mình theo cách mệnh lệnh, bạn sẽ không nhận được lợi ích từ việc sử dụng RxJS. Vì vậy, tốt hơn là sử dụng các toán tử có sẵn để kiểm soát luồng của các sự kiện của bạn.