Perpustakaan RxJS membantu memperkenalkan fitur pemrograman reaktif dan Observable ke JavaScript. Jika Anda seperti saya, Anda mungkin pertama kali mendengarnya saat bekerja dengan Angular, karena banyak fitur kerangka kerja ini langsung didasarkan pada Observables.

Konsep Observables pasti membingungkan pada awalnya. Namun, saat bekerja dengan mereka, saya akhirnya menemukan dua model mental yang akhirnya membantu saya memahami apa itu bagaimana mereka dapat digunakan. Sampai hari ini, ini adalah kerangka acuan saya kapan pun saya perlu bekerja dengan perpustakaan RxJS. Model mental tersebut adalah:

  1. Bayangkan Observables sebagai array asinkron.
  2. Bayangkan operator sebagai corong.

Mari kita jelajahi ini secara mendetail sehingga Anda juga dapat mulai menggunakannya hari ini!

1. Anggaplah Observables sebagai array asinkron.

RxJS.dev mendefinisikan Observable sebagai berikut:

“Yang dapat diamati adalah kumpulan Push yang malas dari berbagai nilai.”

Meskipun sangat ringkas dan akurat, definisi ini masih mengabaikan banyak konsep kontekstual yang hilang untuk memahami sepenuhnya penggunaan praktis Observables.

Untungnya, pada Meetup talk beberapa waktu lalu, Abraham Williams melakukan presentasi tentang Observables dan Angular di mana ia menampilkan diagram kecil yang menjadi Aha besar! momen dalam pemahaman saya tentang apa yang Dapat Diamati. Di dalamnya, dia membahas perpotongan variabel tunggal/multi-nilai dan sinkron/asinkron. Dia melakukan ini untuk menunjukkan di mana Observables cocok dalam gambar, membaginya seperti ini:

Di sinilah semuanya menjadi jelas: secara konseptual, Observables dapat dianggap sebagai array asynchronous!

Sekarang, apa yang membuat sesuatu klik tidak hanya melihat bahwa mereka adalah variabel multinilai, namun juga melihat bagaimana Observable berbeda dari Janji. Promise secara asli didukung dalam JavaScript untuk menangani nilai asinkron tunggal, jadi setelah Promise diselesaikan, maka Promise selesai. Misalnya, cuplikan berikut membuat Janji yang mengembalikan 'bip' ketika diselesaikan setelah satu detik (kami kemudian mengambil string itu dan mencetaknya ke konsol).

Poin utama disini adalah melihat itu, setelah Promise terselesaikan dan tidak akan mengeluarkan apapun lagi.

Di sisi lain, Observable dapat mengeluarkan lebih dari satu nilai dari waktu ke waktu. Kita dapat “membaca” nilai asinkron ini selama kita berlangganan Observable, atau Observable itu sendiri selesai.

Misalnya, cuplikan di bawah ini membuat Observable yang mengeluarkan tiga string ('bip', 'boop', 'bop') sebelum selesai:

Seperti yang Anda lihat, dua nilai pertama ('bip', 'boop') dikeluarkan satu demi satu, tetapi nilai ketiga ('bop') dikeluarkan setelah sepuluh detik. Selama waktu tersebut, subscription tetap “hidup”, menunggu sesuatu yang lain muncul.

Berikut contoh lainnya: Bayangkan kita ingin mencetak ke konsol koordinat kursor mouse setiap kali pengguna mengklik halaman web.

Kita dapat melakukannya dengan menggunakan operator pembuatan RxJS fromEvent(), yang memungkinkan kita membuat Observable yang mengeluarkan data peristiwa setiap kali peristiwa elemen DOM tertentu dipicu (dalam hal ini, document's MouseClick event):

Setelah kami berlangganan observable, itu akan mulai mengeluarkan data peristiwa pada setiap peristiwa klik. Kami kemudian mencetak untuk menghibur koordinat kursor pada saat peristiwa klik terjadi.

Anda dapat mengeklik beberapa kali berturut-turut, atau menunggu dua menit lalu mengeklik lagi, namun selama langganan masih aktif, kami akan terus mencetak koordinatnya.

Jadi, begitulah: Observable seperti array data asinkron.

2. Anggaplah operator RxJS sebagai corong

Model mental lain yang membantu saya lebih memahami cara menanganiYang Dapat Diamati berasal dari video ini oleh Maximilian Schwarzmüller dari Academind.

Dalam video tersebut, dia menyarankan untuk memikirkan operator RxJS sebagai corong yang mengambil nilai yang dipancarkan oleh Observable dan melakukan sesuatu dengannya sebelum meneruskannya ke aliran (misalnya memodifikasinya, membuat efek samping, dll. ).

Berdasarkan contoh peristiwa klik di atas, katakanlah sekarang kita ingin mendeteksi klik ganda berdasarkan seberapa cepat pengguna menekan tombol klik (untuk latihan ini, mengklik lebih dari sekali setiap 250 md akan dianggap sebagai klik ganda). Ketika klik dua kali terdeteksi, kami kemudian mencetak pesan 'klik dua kali!' ke konsol. Berikut kodenya:

Seperti yang Anda lihat, kami menggunakan metode pipe() Observable untuk menyiapkan daftar operator seperti corong yang berurutan untuk membantu kami menangani setiap nilai yang dipancarkan. Namun, sebelum kita mendalami kodenya, mari kita bahas terlebih dahulu apa yang dilakukan masing-masing operator yang terdaftar:

  • bufferTime(): operator yang “mempertahankan” semua nilai yang dipancarkan oleh Observable selama jangka waktu tertentu, dan kemudian mengembalikannya dalam array setelah waktu tersebut berlalu.
  • map(): salah satu operator yang paling umum digunakan, map() berjalan setiap kali Observable mengeluarkan nilai dan memungkinkan kita melakukan sesuatu dengan nilai tersebut. Secara otomatis membungkus apa pun yang kita kembalikan dalam Observable baru sehingga dapat terus ditangani.
  • filter(): mengizinkan nilai yang dipancarkan oleh Observable untuk terus mengalir hanya jika nilai tersebut memenuhi kondisi pemfilteran yang diperlukan.

Jadi, sekarang kita tahu apa yang dilakukan masing-masing operator ini, berikut cara kita menggunakannya dalam kode di atas untuk mencapai tujuan kita:

Pada setiap peristiwa klik:

  1. Gunakan bufferTime()untuk memulai serangkaian peristiwa klik dan tunggu 250 ms lagi untuk melihat apakah ada peristiwa klik lainnya yang terjadi, sehingga menyetel ulang waktu buffer pada setiap klik. Ketika tidak ada lagi klik yang terjadi setelah 250 md, kembalikan Observable baru dengan rangkaian peristiwa klik.
  2. Gunakan map()untuk mengambil array nilai dan mengembalikan Observable baru dengan hanya panjang array sebagai nilainya.
  3. Gunakan filter() untuk hanya mengizinkan nilai melanjutkan aliran jika panjang array lebih besar atau sama dengan 2(yaitu “klik dua kali”).
  4. Di blok subscribe(), cetak 'double click!' ke konsol untuk setiap peristiwa yang berhasil memenuhi kondisi pemfilteran.

Seperti yang Anda lihat, dalam implementasi ini kami mengontrol aliran nilai dengan bufferTime(), memodifikasi nilai menjadi sesuatu yang lebih mudah digunakan dengan map(), dan selanjutnya mengontrol aliran nilai bersyarat dengan filter() sebelum mencapai blok subscribe() untuk melakukan apa yang kami inginkan: cetak pesan ke konsol pada setiap klik ganda.

Jadi begini: operator seperti corong yang membantu kita menangani aliran aliran nilai yang dipancarkan oleh Observable.

Tentu saja, daftar operator RxJS cukup banyak, dan perlu beberapa saat untuk memahami fungsi masing-masing operator, tetapi menganggapnya sebagai corong telah membantu saya mempelajari cara menggunakannya dengan lebih efektif.

Selain itu, model mental ini juga membantu saya mengidentifikasi secara luas jenis operator yang ada:

  • Operator yang membantu Anda mengontrol aliran sungai (misalnya memulainya, menghentikannya, membatasinya, memperlambatnya, dll).
  • Operator yang membantu Anda mengubah data yang dipancarkan oleh aliran.
  • Operator yang membantu Anda berbagi data yang dipancarkan oleh aliran.
  • Operator yang membantu Anda menggabungkan aliran.
  • Operator yang membantu Anda membuat aliran.

Kesimpulan

Ingatlah selalu hal ini: anggap Observable sebagai array asinkron, dan anggap operator sebagai corong yang membantu Anda mengontrol dan mengubah aliran aliran sesuai kebutuhan.

Saya harap ini membantu, dan selamat coding!

Terima kasih kepada Mike Guoynes

Membangun aplikasi web yang dapat disusun

Jangan membangun monolit web. Gunakan Bit untuk membuat dan menyusun komponen perangkat lunak yang dipisahkan — dalam kerangka kerja favorit Anda seperti React atau Node. Bangun frontend dan backend yang skalabel dengan pengalaman pengembangan yang kuat dan menyenangkan.

Bawa tim Anda ke Bit Cloud untuk menghosting dan berkolaborasi dalam berbagai komponen, dan mempercepat, menskalakan, dan menstandardisasi pengembangan sebagai sebuah tim. Mulailah dengan frontend yang dapat dikomposisi seperti Sistem Desain atau Frontend Mikro, atau jelajahi backend yang dapat dikomposisi. Cobalah →

Belajarlah lagi