Rumah >hujung hadapan web >tutorial js >Operasi Async dalam Aplikasi React Redux
mata utama
Artikel ini pada asalnya diterbitkan dalam Codebrahma.
JavaScript adalah bahasa pengaturcaraan tunggal. Maksudnya, apabila anda menulis kod berikut ...
... baris kedua hanya akan dilaksanakan selepas baris pertama dilaksanakan. Ini tidak akan menjadi masalah dalam kebanyakan kes, kerana klien atau pelayan melakukan berjuta -juta pengiraan sesaat. Kami hanya melihat kesan ini apabila kami melakukan pengiraan yang mahal (tugas yang mengambil masa yang agak lama untuk disiapkan - permintaan rangkaian mengambil sedikit masa untuk kembali).
Kenapa saya hanya menunjukkan panggilan API (permintaan rangkaian) di sini? Bagaimana dengan operasi asynchronous lain?
Panggilan API adalah contoh yang sangat mudah dan berguna untuk menerangkan cara mengendalikan operasi tak segerak. Terdapat operasi lain, seperti , pengkomputeran intensif prestasi, pemuatan imej, dan sebarang operasi yang didorong oleh peristiwa.
setTimeout()
Apabila membina aplikasi, kita perlu mempertimbangkan bagaimana pelaksanaan tidak segerak mempengaruhi struktur. Sebagai contoh, fikirkan
fetch()
Pertimbangkan kod ini:
Dalam kes ini, kerana
<code class="language-javascript">userId = fetch(userEndPoint); // 从 userEndpoint 获取 userId userDetails = fetch(userEndpoint, userId) // 为此特定 userId 获取数据。</code>tidak segerak, apabila kita cuba mendapatkan
kita tidak akan mempunyai fetch()
. Oleh itu, kita perlu membinanya dengan cara yang memastikan barisan kedua dilaksanakan hanya selepas baris pertama mengembalikan respons. userDetails
Pelaksanaan permintaan rangkaian yang paling moden adalah tidak segerak. Tetapi ini tidak selalu berfungsi kerana kami bergantung pada data tindak balas API sebelumnya untuk panggilan API berikutnya. Mari kita lihat bagaimana untuk membinanya secara khusus dalam aplikasi ReactJs/Redux.
React adalah perpustakaan depan untuk mewujudkan antara muka pengguna. Redux adalah bekas negara yang menguruskan seluruh keadaan permohonan. Menggunakan React dengan Redux membolehkan kami membuat aplikasi yang cekap dan berskala. Dalam aplikasi reaksi sedemikian, terdapat beberapa cara untuk membina operasi tak segerak. Untuk setiap kaedah, kami akan membincangkan kelebihan dan kekurangannya dari segi faktor -faktor berikut:
1.
userDetails
. Ia termasuk bandar dalam respons. Respons akan menjadi objek:
Katakan titik akhir adalah /details
. Respons akan menjadi array:
<code class="language-javascript">userId = fetch(userEndPoint); // 从 userEndpoint 获取 userId userDetails = fetch(userEndpoint, userId) // 为此特定 userId 获取数据。</code>
menggunakan redux thunk /restuarants/:city
<code class="language-javascript">userDetails: { … city: 'city', … };</code>
Menggunakan Redux Observables
setState
redux-async, redux-promise, redux-async-queue Dalam contoh kami, kami akan menggunakan Perpustakaan Axios untuk mendapatkan data, yang mengembalikan janji apabila kami membuat permintaan rangkaian. Janji itu boleh menghuraikan dan mengembalikan respons atau membuang kesilapan. Jadi sebaik sahaja komponen reaksi dipasang, kita boleh mendapatkannya secara langsung seperti ini:
async/menunggu adalah pelaksanaan baru yang boleh kita gunakan untuk melakukan operasi tak segerak. Sebagai contoh, fungsi yang sama dapat dicapai dengan:secara automatik akan membuat semula dan memuatkan senarai restoran.
Kedua -dua kaedah adalah yang paling mudah. Oleh kerana keseluruhan logik berada di dalam komponen, kita boleh mendapatkan semua data sekaligus selepas komponen dimuatkan.
<code class="language-javascript">['restaurant1', 'restaurant2', …]</code>Kekurangan kaedah ini
Masalah timbul apabila interaksi berasaskan data kompleks berlaku. Sebagai contoh, pertimbangkan situasi berikut:
dari ini kita dapat mengetahui bahawa jika kita memindahkan semua logik pengambilalihan sebelum reducer -i.e., Tindakan atau middleware -maka kita dapat mengedarkan tindakan yang betul pada masa yang tepat. Sebagai contoh, apabila pengambilan bermula, kita boleh mengedarkan
. dispatch({ type: 'FETCH_STARTED' })
dispatch({ type: 'FETCH_SUCCESS' })
mahu membangunkan aplikasi JS React?
menggunakan redux thunk
sebagai parameter fungsi. Kami menggunakan dispatch
untuk mengedarkan tindakan yang diperlukan pada masa yang tepat. Faedahnya ialah: getState
dispatch
<code class="language-javascript">userId = fetch(userEndPoint); // 从 userEndpoint 获取 userId userDetails = fetch(userEndpoint, userId) // 为此特定 userId 获取数据。</code>
Seperti yang anda lihat, kami kini mempunyai kawalan yang baik terhadap jenis tindakan yang diedarkan. Setiap panggilan fungsi (seperti fetchStarted()
, fetchUserDetailsSuccess()
, fetchRestaurantsSuccess()
, dan fetchError()
) akan mengedarkan tindakan objek JavaScript biasa, dan butiran tambahan boleh ditambah jika diperlukan. Jadi sekarang tugas Reducer adalah untuk memproses setiap tindakan dan mengemas kini paparan. Saya tidak membincangkan Reducer kerana ia mudah dari sini dan pelaksanaannya mungkin berbeza.
Untuk membuat kerja ini, kita perlu menyambungkan komponen React untuk redux dan mengikat tindakan ke komponen menggunakan perpustakaan Redux. Setelah selesai, kita hanya boleh memanggil this.props.getRestaurants()
, yang seterusnya akan mengendalikan semua tugas di atas dan mengemas kini paparan mengikut reducer.
Untuk skalabilitasnya, Redux Thunk boleh digunakan untuk aplikasi yang tidak melibatkan kawalan kompleks tindakan tak segerak. Di samping itu, ia berfungsi dengan lancar dengan perpustakaan lain, seperti yang diterangkan dalam topik dalam bahagian berikut.
kita masih boleh melaksanakannya, tetapi ia akan menjadi lebih rumit untuk dilaksanakan dengan tepat. Berbanding dengan perpustakaan lain, kejelasan kod tugas kompleks akan menjadi sedikit lebih teruk dan akan menjadi lebih sukar untuk dikekalkan.
menggunakan redux-saga
redux-saga menyediakan API yang membantu mencapai matlamat berikut:
Pertimbangkan contoh sebelumnya: Jika kita memulakan saga dan konfigurasikannya dengan redux berdasarkan apa yang disebutkan dalam dokumentasinya, kita boleh melakukan perkara berikut:
<code class="language-javascript">userDetails: { … city: 'city', … };</code>Jadi jika kita mengedarkannya menggunakan tindakan mudah jenis
, middleware saga akan mendengar dan bertindak balas. Malah, tiada tindakan yang digunakan oleh middleware. Ia hanya mendengar dan melakukan beberapa tugas lain, dan mengedarkan tindakan baru jika diperlukan. Dengan menggunakan seni bina ini, kita dapat mengedarkan pelbagai permintaan, masing -masing menerangkan: FETCH_RESTAURANTS
dan sebagainya.
Di samping itu, anda dapat melihat kelebihan fetchRestaurantSaga()
. Kami sedang menggunakan API call
untuk melaksanakan panggilan menyekat. SAGA menyediakan API lain, seperti fork()
, yang melaksanakan panggilan yang tidak menyekat. Kami boleh menggabungkan panggilan menyekat dan tidak menyekat untuk mengekalkan struktur yang sesuai untuk permohonan kami.
dengan skalabilitas, menggunakan saga bermanfaat:
seperti yang dinyatakan dalam dokumentasinya, "Epic adalah primitif teras Redux-Observable" Seksyen:
Untuk tugas kami, kami hanya boleh menulis kod berikut:
<code class="language-javascript">userId = fetch(userEndPoint); // 从 userEndpoint 获取 userId userDetails = fetch(userEndpoint, userId) // 为此特定 userId 获取数据。</code>
Pada mulanya, ini mungkin kelihatan agak mengelirukan. Walau bagaimanapun, semakin anda memahami RXJS, semakin mudah untuk mewujudkan epik.
Seperti saga, kita boleh mengedarkan pelbagai tindakan, yang masing -masing menerangkan bahagian rantaian permintaan API yang sedang dalam.
Dari segi skalabilitas, kita boleh memecah atau menggabungkan epik berdasarkan tugas tertentu. Oleh itu, perpustakaan ini dapat membantu membina aplikasi berskala. Jika kita memahami corak penulisan kod yang dapat dilihat, kejelasan kod adalah baik.
Bagaimana untuk menentukan perpustakaan mana yang hendak digunakan? Ia bergantung kepada bagaimana kompleks permintaan API kami.
Bagaimana untuk memilih antara redux-saga dan redux-observable? Ia bergantung kepada penjana pembelajaran atau RXJS. Kedua -duanya adalah konsep yang berbeza, tetapi sama -sama cukup baik. Saya cadangkan untuk mencuba kedua -duanya untuk melihat mana yang lebih baik untuk anda.
Di manakah meletakkan logik perniagaan untuk memproses API? Adalah lebih baik untuk meletakkannya sebelum pengurangan, tetapi tidak dalam komponen. Cara terbaik adalah di middleware (menggunakan saga atau diperhatikan).
Anda boleh membaca lebih banyak artikel pembangunan React di Codebrahma.
Middleware di Redux memainkan peranan penting dalam mengendalikan operasi tak segerak. Ia menyediakan titik lanjutan pihak ketiga antara tindakan pengedaran dan tindakan itu tiba di pengurangan. Middleware boleh digunakan untuk merakam, mengubah suai, dan juga membatalkan tindakan, serta untuk mengedarkan tindakan lain. Dalam konteks operasi asynchronous, middleware seperti Redux Thunk atau Redux Saga membolehkan anda menulis pencipta tindakan yang mengembalikan fungsi dan bukannya tindakan. Fungsi ini kemudiannya boleh digunakan untuk melambatkan pengedaran tindakan atau hanya mengedarkan tindakan apabila keadaan tertentu dipenuhi.
Redux Thunk adalah middleware yang membolehkan anda menulis pencipta tindakan yang mengembalikan fungsi dan bukannya tindakan. Thunk boleh digunakan untuk melambatkan pengagihan tindakan atau untuk mengedarkan tindakan hanya apabila syarat -syarat tertentu dipenuhi. Ciri ini menjadikannya alat yang sangat baik untuk mengendalikan operasi tak segerak di Redux. Sebagai contoh, anda boleh mengedarkan tindakan untuk menunjukkan permulaan panggilan API, dan kemudian mengedarkan tindakan lain apabila panggilan kembali data atau mesej ralat.
Redux Thunk dan Redux Saga adalah kedua -dua middleware untuk menguruskan kesan sampingan di Redux, termasuk operasi tak segerak. Perbezaan utama antara keduanya adalah pendekatan mereka. Redux Thunk menggunakan fungsi panggilan balik untuk mengendalikan operasi tak segerak, manakala Redux Saga menggunakan fungsi penjana dan lebih banyak kaedah deklaratif. Ini menjadikan Redux saga lebih kuat dan fleksibel, tetapi juga lebih kompleks. Sekiranya aplikasi anda mempunyai operasi tak segerak yang mudah, Redux Thunk mungkin cukup. Walau bagaimanapun, untuk senario yang lebih kompleks yang melibatkan keadaan kaum, pembatalan, dan logik jika else, redux saga mungkin pilihan yang lebih baik.
Tindakan boleh diedarkan apabila ralat berlaku semasa operasi tidak segerak untuk mengendalikan pengendalian ralat dalam operasi tak segerak dalam Redux. Tindakan ini boleh mengambil mesej ralat sebagai muatannya. Anda kemudian boleh mengendalikan tindakan ini dalam pengurangan untuk mengemas kini status dengan mesej ralat. Dengan cara ini, mesej ralat boleh dipaparkan kepada pengguna atau direkodkan untuk debugging.
Tindakan Asynchronous di Redux boleh diuji dengan mengejek penyimpanan Redux dan panggilan API. Untuk penyimpanan Redux, anda boleh menggunakan perpustakaan seperti redux-mock-store
. Untuk panggilan API, anda boleh menggunakan perpustakaan seperti fetch-mock
atau nock
. Dalam ujian anda, anda boleh mengedarkan tindakan tak segerak dan kemudian menegaskan bahawa tindakan yang diharapkan telah diedarkan dengan muatan yang betul.
middleware seperti redux saga boleh digunakan untuk membatalkan operasi tak segerak di Redux. Redux Saga menggunakan fungsi penjana, yang boleh dibatalkan menggunakan kesan cancel
. Apabila cancel
kesan dihasilkan, saga akan dibatalkan dari titik permulaannya sehingga kesan semasa dibatalkan.
middleware seperti redux saga boleh digunakan untuk mengendalikan keadaan perlumbaan dalam operasi tak segerak di Redux. Redux Saga menyediakan kesan seperti takeLatest
dan takeEvery
yang boleh digunakan untuk mengendalikan tindakan serentak. Sebagai contoh, jika tugas saga yang bermula sebelum ini masih berjalan apabila tindakan baru diedarkan, takeLatest
membatalkan tugas.
redux thunk secara asli menyokong async/menunggu. Dalam pencipta tindakan anda, anda boleh mengembalikan fungsi tak segerak dan bukannya fungsi biasa. Di dalam fungsi asynchronous ini, anda boleh menggunakan async/menunggu untuk mengendalikan operasi tak segerak. Apabila operasi asynchronous selesai, fungsi dispatch
boleh dipanggil menggunakan objek tindakan.
Keadaan pemuatan dalam operasi tak segerak di Redux boleh dikendalikan dengan mengedarkan tindakan sebelum dan selepas operasi tak segerak. Tindakan yang diedarkan sebelum operasi dapat menetapkan status beban kepada benar, dan tindakan yang diedarkan setelah operasi dapat menetapkannya kepada palsu. Dalam pengurangan anda, anda boleh mengendalikan tindakan ini untuk mengemas kini keadaan beban dalam storan.
Kesan sampingan di redux boleh dikendalikan menggunakan middleware seperti redux thunk atau redux saga. Middleware ini membolehkan anda menulis pencipta tindakan yang mengembalikan fungsi dan bukannya tindakan. Fungsi ini boleh digunakan untuk melakukan kesan sampingan seperti operasi asynchronous, pembalakan, dan tindakan mengedarkan keadaan.
Atas ialah kandungan terperinci Operasi Async dalam Aplikasi React Redux. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!