Minggu lalu saya menjawab pertanyaan RxJS di mana saya berdiskusi dengan anggota komunitas lain tentang: "Haruskah saya membuat langganan untuk setiap efek samping tertentu atau haruskah saya mencoba meminimalkan langganan secara umum?" Saya ingin tahu metodologi apa yang digunakan dalam hal pendekatan aplikasi reaktif penuh atau kapan harus beralih dari satu ke yang lain. Ini akan membantu saya dan mungkin orang lain untuk menghindari diskusi yang tidak penting.
Info pengaturan
- Semua contoh dalam TypeScript
- Untuk fokus yang lebih baik pada pertanyaan, jangan gunakan siklus hidup / konstruktor untuk langganan dan untuk tetap dalam kerangka yang tidak terkait
- Bayangkan: Langganan ditambahkan dalam konstruktor / siklus hidup init
- Bayangkan: Berhenti berlangganan dilakukan dalam menghancurkan siklus hidup
Apa itu efek samping (Sampel sudut)
- Perbarui / Input di UI (mis.
value$ | async
) - Output / Hulu komponen (misalnya
@Output event = event$
) - Interacton antara layanan yang berbeda pada hierarki yang berbeda
Contoh penggunaan contoh:
- Dua fungsi:
foo: () => void; bar: (arg: any) => void
- Dua sumber yang bisa diamati:
http$: Observable<any>; click$: Observable<void>
foo
dipanggil setelahhttp$
dipancarkan dan tidak memerlukan nilaibar
dipanggil setelahclick$
dipancarkan, tetapi membutuhkan nilai saat ini darihttp$
Kasus: Buat langganan untuk setiap efek samping tertentu
const foo$ = http$.pipe(
mapTo(void 0)
);
const bar$ = http$.pipe(
switchMap(httpValue => click$.pipe(
mapTo(httpValue)
)
);
foo$.subscribe(foo);
bar$.subscribe(bar);
Kasus: Minimalkan langganan secara umum
http$.pipe(
tap(() => foo()),
switchMap(httpValue => click$.pipe(
mapTo(httpValue )
)
).subscribe(bar);
Pendapat saya sendiri singkatnya
Saya dapat memahami fakta bahwa langganan membuat lanskap Rx lebih rumit pada awalnya, karena Anda harus memikirkan bagaimana pelanggan harus memengaruhi pipa atau tidak misalnya (bagikan pengamatan Anda atau tidak). Tetapi semakin Anda memisahkan kode Anda (semakin Anda fokus: apa yang terjadi ketika) semakin mudah untuk mempertahankan (menguji, men-debug, memperbarui) kode Anda di masa depan. Dengan mengingat hal itu saya selalu membuat satu sumber yang dapat diamati dan satu langganan untuk setiap efek samping dalam kode saya. Jika dua atau lebih efek samping yang saya miliki dipicu oleh sumber yang sama persis yang dapat diamati, maka saya membagikan pengamatan saya dan berlangganan untuk setiap efek samping secara individual, karena dapat memiliki siklus hidup yang berbeda.
sumber
takeUntil
kombinasi dengan fungsi yang dipanggil daringOnDestroy
. Ini adalah salah satu kapal yang menambahkan ini ke pipa:takeUntil(componentDestroyed(this))
. stackoverflow.com/a/60223749/5367916jika mengoptimalkan langganan adalah tujuan akhir Anda, mengapa tidak pergi ke ekstrim logis dan ikuti saja pola umum ini:
Mengeksekusi efek samping secara eksklusif di ketuk dan mengaktifkan dengan penggabungan berarti Anda hanya memiliki satu langganan.
Salah satu alasan untuk tidak melakukan ini adalah karena Anda mensterilkan banyak hal yang membuat RxJS berguna. Yaitu kemampuan untuk menyusun aliran yang dapat diamati, dan berlangganan / berhenti berlangganan dari aliran sebagaimana diperlukan.
Saya berpendapat bahwa yang dapat diamati Anda harus disusun secara logis, dan tidak dicemari atau dikacaukan atas nama pengurangan langganan. Haruskah efek foo secara logis digabungkan dengan efek bar? Apakah yang satu membutuhkan yang lain? Apakah saya akan pernah tidak ingin memicu foo ketika http $ emit? Apakah saya membuat sambungan yang tidak perlu antara fungsi yang tidak terkait? Ini semua adalah alasan untuk menghindari menempatkan mereka dalam satu aliran.
Ini semua bahkan tidak mempertimbangkan penanganan kesalahan yang lebih mudah dikelola dengan beberapa langganan IMO
sumber