Secara singkat tentang saluran redux-saga

Selamat siang, teman-teman terkasih.


Dalam artikel ini saya ingin menggambarkan mekanisme saluran redux-saga sesederhana dan sesingkat mungkin, menggunakan contoh yang dekat dengan kasus nyata, saya harap ini berhasil untuk saya.


Jadi mari kita mulai.


Masalah model menonton-dan-garpu


Misalkan kita memiliki model jam tangan dan garpu biasa, dengan bentuk berikut:


import { take, fork } from 'redux-saga/effects' function* watchRequest() { while (true) { const {payload} = yield take('INIT_REQUEST'); // ,     yield fork(makeRequest, payload); } } function* makeRequest(payload) { //   } 

Pendekatan ini buruk karena ketika menangkap beberapa peristiwa INIT_REQUEST yang mengikuti satu demi satu, beberapa eksekusi makeRequest akan makeRequest , masing-masing. Yang pada gilirannya dapat menyebabkan mereka β€œberlomba”.


Dan di sini mekanisme saluran datang untuk membantu kami.


Saluran memiliki buffer, dengan demikian membantu mengatur acara yang masuk (misalnya, INIT_REQUEST ), dan mengatur eksekusi berurutan mereka (misalnya, makeRequest akan dieksekusi beberapa kali secara berurutan).


Secara kasar, saluran membentuk antrian FIFO untuk eksekusi berurutan.


Klasifikasi berdasarkan sumber acara:


  • channel - acara diantrekan secara manual menggunakan put ;
  • actionChannel - acara ditangkap di dekat toko redux;
  • eventChannel - sumber acara eksternal, paling sering soket web;

Jadi, kami akan menganalisis secara singkat masing-masing.


Lebih banyak di saluran


Saluran semacam itu biasanya menyelesaikan masalah komunikasi antar kisah. Sangat jarang digunakan. Misalnya, jika Anda perlu mengoordinasikan beberapa permintaan mulai pada saat yang sama.


 channel([buffer]) 

Ini memiliki argumen buffer tunggal - buffer yang terakumulasi (kami akan memeriksa buffer secara lebih rinci di bawah).


Lebih lanjut tentang actionChannel


Ini paling sering digunakan ketika perlu untuk merespons acara dari toko redux.


 actionChannel(pattern, [buffer]) 

Dibutuhkan dua argumen:


  • pattern - pola acara yang diinginkan, serta take ;
  • buffer - akumulasi buffer;

Contoh singkat penggunaan:


 import { take, actionChannel, call } from 'redux-saga/effects' function* watchRequest() { const requestChannel = yield actionChannel('INIT_REQUEST') while (true) { const {payload} = yield take(requestChannel); //      yield call(makeRequest, payload); } } function* makeRequest(payload) { //   } 

Lebih lanjut tentang eventChannel


Biasanya mereka memecahkan masalah komunikasi melalui soket web yang melewatinya.


 eventChannel(subscribe, [buffer], [matcher]) 

Dibutuhkan tiga argumen:


  • subscribe adalah fungsi yang menginisialisasi sumber acara eksternal (dalam contoh di bawah ini, setTimeout). Dalam argumen, panggilan balik disebut emitor, yang akan dipanggil ketika perlu untuk mengirim data ke saluran dari sumber. Kembali harus berhenti berfungsi;
  • buffer - akumulasi buffer;
  • matcher - berfungsi untuk memfilter pesan masuk.

Contoh singkat penggunaan:


 import { eventChannel, END } from 'redux-saga' import { take, put, call } from 'redux-saga/effects' function initSocketChannel(query) { return eventChannel(emitter => { //     web socket const handshakeTimeoutId = setTimeout(() => { emitter('handshake - ok'); }, 100); const messageTimeoutId = setTimeout(() => { emitter('message'); }, 500); const endTimeoutId = setTimeout(() => { emitter(END); }, 1000); //     return () => { clearTimeout(handshakeTimeoutId); clearTimeout(messageTimeoutId); clearTimeout(endTimeoutId); } } ) } export function* saga() { const chan = yield call(initSocketChannel, query) try { while (true) { const message = yield take(chan); //    END   brake console.log(`socket : ${message}`) } } finally { console.log('socket terminated') } } 

Tentunya Anda memperhatikan kehadiran konstanta END - ini adalah tindakan, yang berarti akhir komunikasi dengan saluran.


Dalam kode sumber, redux-saga direpresentasikan sebagai berikut:


 var CHANNEL_END_TYPE = '@@redux-saga/CHANNEL_END'; var END = { type: CHANNEL_END_TYPE }; var isEnd = function isEnd(a) { return a && a.type === CHANNEL_END_TYPE; }; 

dan dalam kode sumber eventChannel melihat skrip berikut


 function eventChannel(subscribe) { … if (isEnd(input)) { close(); return; } ... } 

Apa itu buffer?


Ini perlu diperhatikan, karena setiap saluran memiliki buffer dasar, dan dengan itu, antrian untuk pemrosesan terbentuk.


Contoh membuat buffer:


 import { buffers } from 'redux-saga' const buffer = buffers.sliding(5); 

buffers adalah turunan dari pabrik untuk membuat buffer dengan strategi yang berbeda.


Hanya 5 strategi, metode yang sesuai dengan mereka:


  • buffers.none() - tidak ada buffering, pesan baru akan hilang jika tidak ada peserta yang tertunda;
  • buffers.fixed(limit) - pesan baru akan di-buffer hingga batasnya. Kesalahan overflow akan menghasilkan pengecualian. Batas default adalah 10;
  • buffers.expanding(initialSize) - seperti diperbaiki, tetapi overflow akan menyebabkan buffer berkembang secara dinamis;
  • buffers.dropping(limit) sama dengan fix, tetapi overflow akan secara diam-diam membuang pesan;
  • buffers.sliding(limit) sama dengan diperbaiki, tetapi overflow akan menambahkan pesan baru ke akhir dan menghapus pesan terlama di buffer.

Alih-alih mematikan


Jadi, kami memeriksa mengapa mekanisme saluran ditemukan, dan dalam tugas praktis apa yang digunakan.


Saya harap setelah membaca ide umum dan dunia menjadi sedikit lebih mudah.

Source: https://habr.com/ru/post/id432070/


All Articles