angular - Penanganan aksi NgRx asinkron


Saya memiliki aplikasi Angular, dan tampilan utama dibagi menjadi 2 komponen. Ini akan terkait dengan penanganan pengiriman aksi NgRx, secara asinkron.

1) MenuComponent - ini berisi berbagai tombol navigasi, seperti tombol keluar. Saat mengeklik tombol keluar, itu memanggil authenticationService.logout(), yang mengirim permintaan http ke backend, diikuti dengan keluar dari pengguna. Oleh karena itu, ini adalah operasi asinkron.

public logout() {
  this.authenticationService.logout();
  this.router.navigate(['login']);
}

2) DashboardComponent - Saya telah menulis berikut ini untuk menangani hook siklus hidup OnDestroy, yang akan dipanggil setiap kali komponen dihancurkan. Ini menggunakan NgRx untuk manajemen state.

ngOnDestroy() {
  this.store.dispatch(new UpdateDashboardConfiguration());
  this.store.dispatch(new ClearDashboardState());
}

Pengiriman aksi UpdateDashboardConfiguration() akan mengakibatkan aplikasi mengirim permintaan http ke server untuk menyimpan konfigurasi dashboard, oleh karena itu ini juga bersifat asinkron.

Pertanyaan utamanya adalah, ketika pengguna memutuskan untuk logout dengan mengklik tombol logout pada MenuComponent, apakah ada cara untuk memastikan bahwa pengiriman UpdateDashboardConfiguration() akan selesai sebelum pengiriman aksi ClearDashboardState(), serta authenticationService.logout() dari MenuComponent lainnya dipanggil?

Alur yang disukai adalah sebagai berikut:

UpdateDashboardConfiguration => ClearDashboardState => logout()

Bagi mereka yang penasaran, this.store.dispatch(new UpdateDashboardConfiguration()).subscribe(...) tidak akan berhasil karena store.dispatch() memiliki tipe void, dan bukan observable.

Terima kasih sebelumnya.

Bagi mereka yang tertarik, ini adalah Effect untuk aksi UpdateDashboardConfiguration.

@Effect()
UpdateDashboardConfiguration$ = this.actions$.pipe(
  ofType<UpdateDashboardConfiguration>.(DashboardActionTypes.UpdateDashboardWidget),
  withLatestFrom(this.store.select(selectDashboardLayoutStateConfig)),
  switchMap(action => {
    return this.dashboardService.updateDashboardConfiguration(action).pipe(
      map(data => (new UpdateDashboardConfigurationSuccess(data))),
    );
  }
  ),
);

Jawaban #1

Sepertinya Anda perlu memodifikasi apa yang dilakukan oleh fungsi logout Anda. Jika Anda memiliki urutan tindakan yang diinginkan untuk dijalankan, Anda sebaiknya tidak membiarkannya berjalan secara asinkron.

Karena Anda menggunakan NgRx, Anda sebaiknya mengirimkan aksi LogoutClicked daripada memanggil fungsi layanan. Ini akan memungkinkan Anda mengontrol alur sehingga Anda dapat menangani semuanya dalam urutan yang benar. Anda dapat menyiapkan efek yang menangani LogoutClicked dan mengirimkan aksi UpdateDashboardConfiguration. Kemudian, saat Anda menangani UpdateDashboardConfigurationSuccess, Anda dapat memutuskan apakah perlu mengirimkan aksi ClearDashboardState, dan dari situ Anda akhirnya dapat mengirimkan aksi Logout yang memanggil fungsi layanan logout Anda.

Anda mungkin perlu memperbarui payload yang ada di dalam aksi Anda untuk membantu efek membuat keputusan tentang aksi mana yang harus dikirim selanjutnya. Anda dapat menggunakan pola efek Content-Based Decider yang ditemukan di sini.