Rumah >hujung hadapan web >tutorial js >Operasi Async dalam Aplikasi React Redux

Operasi Async dalam Aplikasi React Redux

Lisa Kudrow
Lisa Kudrowasal
2025-02-16 12:02:12517semak imbas

Async Operations in React Redux Applications

mata utama

    Sifat tunggal JavaScript bermakna bahawa operasi tak segerak, seperti panggilan API, adalah kritikal untuk UI yang tidak menyekat, dan pengendalian operasi yang cekap adalah kritikal dalam aplikasi REDUX React.
  • Redux Thunk, Redux-Saga, dan Redux-Observables adalah popular Redux Asynchronous Operasi Pengurusan Middleware, masing-masing memberikan kelebihan yang berbeza berdasarkan kerumitan dan keperluan aplikasi.
  • Redux Thunk memudahkan pengagihan tindakan tak segerak dengan membenarkan fungsi pulangan dan bukannya tindakan, membolehkan panggilan API berurutan dan memproses data berkaitan dalam fungsi ini.
  • redux-saga memanfaatkan penjana ES6 untuk menyediakan penyelesaian yang lebih kuat untuk senario kompleks seperti mengendalikan keadaan perlumbaan, jeda, dan membatalkan operasi, menjadikannya sesuai untuk aplikasi besar.
  • Redux-Observables memanfaatkan RXJS untuk menyediakan cara yang kuat untuk menguruskan kesan sampingan melalui aliran tindakan, memberikan skalabilitas dan kawalan yang sangat baik ke atas operasi asynchronous dalam seni bina aplikasi kompleks.

Artikel ini pada asalnya diterbitkan dalam Codebrahma.

JavaScript adalah bahasa pengaturcaraan tunggal. Maksudnya, apabila anda menulis kod berikut ...

Async Operations in React Redux Applications ... 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

sebagai fungsi yang melakukan panggilan API (permintaan rangkaian) dari penyemak imbas. (Abaikan sama ada ia adalah permintaan Ajax. Hanya merawat tingkah lakunya sebagai asynchronous atau segerak.) Masa berlalu apabila permintaan diproses pada pelayan tidak berlaku pada benang utama. Oleh itu, kod JS anda akan terus melaksanakan dan sebaik sahaja permintaan itu mengembalikan respons, ia akan mengemas kini thread.

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:

  • CODE CLOLERITY
  • Skalabiliti
  • mudah mengendalikan ralat
Untuk setiap kaedah, kami akan melaksanakan kedua -dua panggilan API ini:

1.

Katakan titik akhir adalah userDetails. Ia termasuk bandar dalam respons. Respons akan menjadi objek:

2.

Katakan titik akhir adalah /details. Respons akan menjadi array:

<code class="language-javascript">userId = fetch(userEndPoint); // 从 userEndpoint 获取 userId
userDetails = fetch(userEndpoint, userId) // 为此特定 userId 获取数据。</code>

ingat bahawa kita hanya boleh membuat permintaan kedua selepas permintaan pertama selesai (kerana ia bergantung pada permintaan pertama). Mari kita lihat pelbagai kaedah: Gunakan janji atau async/tunggu secara langsung dengan

menggunakan redux thunk /restuarants/:city

menggunakan redux-saga
<code class="language-javascript">userDetails: {
  …
  city: 'city',
  …
};</code>

Menggunakan Redux Observables

  • Saya secara khusus memilih kaedah di atas kerana ia adalah kaedah yang paling biasa digunakan dalam projek besar. Masih ada kaedah lain yang mungkin lebih spesifik untuk tugas tertentu dan tidak mempunyai semua ciri yang diperlukan oleh aplikasi yang kompleks (mis. setState redux-async, redux-promise, redux-async-queue
  • ).
  • Janji
  • Janji adalah objek yang boleh menghasilkan satu nilai pada suatu masa di masa depan: nilai parsed atau sebab yang tidak dapat diselesaikan (contohnya, ralat rangkaian berlaku). - Eric Elliot

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:

Dengan cara ini, apabila keadaan berubah (disebabkan oleh pengambilalihan), komponen

secara automatik akan membuat semula dan memuatkan senarai restoran.

async/menunggu adalah pelaksanaan baru yang boleh kita gunakan untuk melakukan operasi tak segerak. Sebagai contoh, fungsi yang sama dapat dicapai dengan:

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:

Async Operations in React Redux Applications

    Kami tidak mahu benang melaksanakan JS disekat oleh permintaan rangkaian.
  • Semua situasi di atas menjadikan kod ini sangat rumit dan sukar untuk mengekalkan dan menguji.
  • Juga, skalabiliti akan menjadi masalah besar kerana jika kita merancang untuk menukar aliran aplikasi, kita perlu mengeluarkan semua operasi pengambilan dari komponen.
  • Bayangkan apa yang akan kita lakukan jika komponen berada di atas pokok induk-anak. Kemudian kita perlu menukar semua komponen perwakilan yang bergantung kepada data.
  • Juga ambil perhatian bahawa keseluruhan logik perniagaan berada di dalam komponen.
Bagaimana kita memperbaiki?

  1. Pengurusan status menggunakan penyimpanan global sebenarnya boleh menyelesaikan separuh daripada masalah kami dalam kes ini. Kami akan menggunakan Redux sebagai penyimpanan global kami.

  2. Pindahkan logik perniagaan ke tempat yang betul jika kita mempertimbangkan untuk memindahkan logik perniagaan dari komponen, di mana sebenarnya kita boleh melakukan ini? Dalam tindakan? Dalam pengurangan? Melalui middleware? Senibina Redux adalah segerak. Sebaik sahaja anda mengedarkan tindakan (objek JS) dan ia mencapai storan, pengurangan akan beroperasi di atasnya.

  3. Pastikan terdapat benang berasingan yang melaksanakan kod tak segerak dan bahawa sebarang perubahan kepada keadaan global dapat diambil oleh langganan

Async Operations in React Redux Applications 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

, dan apabila ia selesai, kita boleh mengedarkan

. dispatch({ type: 'FETCH_STARTED' }) dispatch({ type: 'FETCH_SUCCESS' }) mahu membangunkan aplikasi JS React?

menggunakan redux thunk

Redux Thunk adalah middleware untuk redux. Ia pada dasarnya membolehkan kita mengembalikan fungsi dan bukannya objek sebagai tindakan. Ini membantu dengan menyediakan

dan

sebagai parameter fungsi. Kami menggunakan dispatch untuk mengedarkan tindakan yang diperlukan pada masa yang tepat. Faedahnya ialah: getState dispatch

Benarkan pengagihan berganda dalam fungsi
  • Persatuan Logik Perniagaan dengan pengambilalihan akan dipindahkan dari komponen React kepada tindakan.
  • Dalam contoh kita, kita boleh menulis semula tindakan seperti ini:
<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.

Walau bagaimanapun, masih agak sukar untuk melaksanakan tugas -tugas tertentu menggunakan Redux Thunk. Sebagai contoh, kita perlu menjeda operasi pengambilan pertengahan, atau hanya membenarkan panggilan terkini apabila terdapat banyak panggilan sedemikian, atau jika API lain mendapatkan data ini dan kita perlu membatalkannya.

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

Dengan middleware redux-saga, kita boleh mendapatkan kelebihan tambahan untuk menangani kebanyakan ciri di atas. Redux-saga dibangunkan berdasarkan penjana ES6.

redux-saga menyediakan API yang membantu mencapai matlamat berikut:

    menyekat peristiwa, menyekat benang pada baris yang sama sehingga beberapa operasi selesai
  • peristiwa yang tidak menyekat, menjadikan kod asynchronous
  • mengendalikan persaingan antara pelbagai permintaan asynchronous
  • jeda/throttling/de-bounce sebarang tindakan
bagaimana saga berfungsi?

SAGA menggunakan gabungan penjana ES6 dan API async/menunggu untuk memudahkan operasi asynchronous. Ia pada dasarnya berfungsi pada benang yang berasingan di mana kita boleh membuat pelbagai panggilan API. Kita boleh menggunakan API mereka untuk membuat setiap panggilan segerak atau tidak segerak, bergantung kepada kes penggunaan. API menyediakan keupayaan untuk membuat thread menunggu pada baris yang sama sehingga permintaan mengembalikan respons. Selain itu, perpustakaan ini menyediakan banyak API lain, yang membuat permintaan API sangat mudah dikendalikan.

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

  • bilakah permintaan pertama akan bermula?
  • bilakah permintaan pertama akan diselesaikan
  • bilakah permintaan kedua akan bermula?

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:

  • kita boleh membina dan kumpulan saga berdasarkan tugas tertentu. Kita boleh mencetuskan saga dari saga lain dengan hanya mengedarkan tindakan.
  • Oleh kerana ia adalah middleware, tindakan yang kami tulis akan menjadi objek JS biasa, tidak seperti Thunk.
  • Oleh kerana kita meletakkan logik perniagaan di dalam saga (yang merupakan middleware), lebih mudah untuk memahami bahagian reaksi jika kita tahu apa yang saga mampu.
  • ralat boleh dipantau dengan mudah dan diedarkan ke penyimpanan melalui mod Cuba/tangkapan.

menggunakan redux-observables

seperti yang dinyatakan dalam dokumentasinya, "Epic adalah primitif teras Redux-Observable" Seksyen:

  1. Epic adalah fungsi yang menerima aliran tindakan dan mengembalikan aliran tindakan. Iaitu, Epic berjalan selari dengan saluran pengedaran Redux biasa, selepas pengurangan telah menerimanya.
  2. Tindakan sentiasa berjalan melalui pengurangan sebelum Epic menerima mereka. Epic menerima dan mengeluarkan hanya aliran tindakan lain. Ini sama dengan Redux-saga, kerana tidak ada tindakan yang digunakan oleh middleware. Ia hanya mendengar dan melakukan beberapa tugas lain.

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.

Keutamaan saya

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.

Soalan Lazim Mengenai Operasi Asynchronous dalam Aplikasi React-Redux

Apakah peranan middleware dalam mengendalikan operasi tak segerak di Redux?

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.

Bagaimanakah Redux Thunk membantu menguruskan operasi tak segerak?

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.

Apakah perbezaan antara Redux Thunk dan Redux Saga?

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.

Bagaimana menangani kesilapan dalam operasi asynchronous di Redux?

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.

Bagaimana untuk menguji tindakan tak segerak di Redux?

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.

Bagaimana untuk membatalkan operasi tak segerak di Redux?

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.

Bagaimana menangani keadaan perlumbaan dalam operasi tak segerak di Redux?

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.

bagaimana menggunakan async/menunggu dengan redux thunk?

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.

Bagaimana untuk mengendalikan keadaan memuatkan dalam operasi tak segerak di Redux?

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.

Bagaimana menangani kesan sampingan di Redux?

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!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn