Model Kereaktifan Diterangkan
kata pengantar
Sudah (sudah) 10 tahun saya mula membangunkan aplikasi dan tapak web, tetapi ekosistem JavaScript tidak pernah lebih menarik daripada hari ini!
Pada tahun 2022, komuniti terpikat dengan konsep "Isyarat" sehingga kebanyakan rangka kerja JavaScript menyepadukannya ke dalam enjin mereka sendiri. Saya sedang memikirkan tentang Preact, yang telah menawarkan pembolehubah reaktif yang diasingkan daripada kitaran hayat komponen sejak September 2022; atau lebih baru Angular, yang melaksanakan Isyarat secara eksperimen pada Mei 2023, kemudian secara rasmi bermula dari versi 18. Pustaka JavaScript lain juga telah memilih untuk memikirkan semula pendekatan mereka...
Antara 2023 dan sehingga kini, saya telah menggunakan Signals secara konsisten merentas pelbagai projek. Kesederhanaan pelaksanaan dan penggunaannya telah meyakinkan saya sepenuhnya, sehinggakan saya telah berkongsi manfaatnya dengan rangkaian profesional saya semasa bengkel teknikal, sesi latihan dan persidangan.
Tetapi baru-baru ini, saya mula bertanya pada diri sendiri sama ada konsep ini benar-benar "revolusioner" / adakah terdapat alternatif kepada Isyarat? Jadi, saya mendalami refleksi ini dan menemui pendekatan yang berbeza untuk sistem reaktif.
Siaran ini ialah gambaran keseluruhan model kereaktifan yang berbeza, bersama-sama dengan pemahaman saya tentang cara ia berfungsi.
NB: Pada ketika ini, anda mungkin sudah meneka, saya tidak akan membincangkan tentang "Arus Reaktif" Java; jika tidak, saya akan menamakan siaran ini "WTF Is Backpressure!?" ?
Teori
Apabila kita bercakap tentang model kereaktifan, kita (pertama sekali) bercakap tentang "pengaturcaraan reaktif", tetapi terutamanya tentang "reaktiviti".
pengaturcaraan reaktif ialah paradigma pembangunan yang membolehkan secara automatik menyebarkan perubahan sumber data kepada pengguna.
Jadi, kita boleh mentakrifkan reaktiviti sebagai keupayaan untuk mengemas kini kebergantungan dalam masa nyata, bergantung pada perubahan data.
NB: Ringkasnya, apabila pengguna mengisi dan/atau menyerahkan borang, kami mesti bertindak balas terhadap perubahan ini, memaparkan komponen pemuatan atau apa-apa lagi yang menyatakan sesuatu sedang berlaku. .. Contoh lain, apabila menerima data secara tak segerak, kita mesti bertindak balas dengan memaparkan semua atau sebahagian daripada data ini, melaksanakan tindakan baharu, dsb.
Dalam konteks ini, perpustakaan reaktif menyediakan pembolehubah yang mengemas kini dan menyebarkan secara automatik dengan cekap, menjadikannya lebih mudah untuk menulis kod yang ringkas dan dioptimumkan.
Untuk menjadi cekap, sistem ini mesti mengira semula/menilai semula pembolehubah ini jika, dan hanya jika, nilainya telah berubah! Dengan cara yang sama, untuk memastikan data yang disiarkan kekal konsisten dan terkini, sistem mesti mengelak daripada memaparkan sebarang keadaan perantaraan (terutamanya semasa pengiraan perubahan keadaan).
NB: Keadaan merujuk kepada data/nilai yang digunakan sepanjang hayat program/aplikasi.
Baiklah, tetapi kemudian… Apakah sebenarnya "model kereaktifan" ini?
PUSH, a.k.a Kereaktifan "Bersemangat".
Model kereaktifan pertama dipanggil "PUSH" (atau kereaktifan "bersemangat"). Sistem ini adalah berdasarkan prinsip berikut:
- Pemulaan sumber data (seperti yang dikenali sebagai "Boleh Diperhatikan")
- Komponen/Fungsi melanggan sumber data ini (ini adalah pengguna)
- Apabila nilai berubah, data disebarkan serta-merta kepada pengguna (seperti yang dikenali sebagai "Pemerhati")
Seperti yang anda duga, model "PUSH" bergantung pada corak reka bentuk "Boleh Diperhatikan/Pemerhati".
Kes Penggunaan Pertama : Keadaan Awal dan Perubahan Keadaan
Mari kita pertimbangkan keadaan awal berikut,
let a = { firstName: "John", lastName: "Doe" }; const b = a.firstName; const c = a.lastName; const d = `${b} ${c}`;
Menggunakan perpustakaan reaktif (seperti RxJS), keadaan awal ini akan kelihatan lebih seperti ini:
let a = observable.of({ firstName: "John", lastName: "Doe" }); const b = a.pipe(map((a) => a.firstName)); const c = a.pipe(map((a) => a.lastName)); const d = merge(b, c).pipe(reduce((b, c) => `${b} ${c}`));
NB: Demi siaran ini, semua coretan kod hendaklah dianggap sebagai "pseudo-code."
Sekarang, mari kita anggap bahawa pengguna (contohnya komponen) mahu merekodkan nilai keadaan D apabila sumber data ini dikemas kini,
d.subscribe((value) => console.log(value));
Komponen kami akan melanggan aliran data; ia masih perlu mencetuskan perubahan,
a.next({ firstName: "Jane", lastName: "Doe" });
Dari situ, sistem "PUSH" mengesan perubahan dan menyiarkannya secara automatik kepada pengguna. Berdasarkan keadaan awal di atas, berikut ialah perihalan operasi yang mungkin berlaku:
- Perubahan keadaan berlaku dalam sumber data A!
- Nilai A disebarkan kepada B (pengiraan sumber data B);
- Kemudian, nilai B disebarkan kepada D (pengiraan sumber data D);
- Nilai A disebarkan kepada C (pengiraan sumber data C);
- Akhir sekali, nilai C disebarkan kepada D (pengiraan semula sumber data D);
Salah satu cabaran sistem ini terletak pada susunan pengiraan. Sesungguhnya, berdasarkan kes penggunaan kami, anda akan mendapati bahawa D mungkin dinilai dua kali: kali pertama dengan nilai C dalam keadaan sebelumnya; dan kali kedua dengan nilai C terkini! Dalam model kereaktifan jenis ini, cabaran ini dipanggil "Masalah Berlian" ♦️.
Kes Penggunaan Kedua : Lelaran Seterusnya
Sekarang, mari kita anggap negeri bergantung pada dua sumber data utama,
let a = { firstName: "John", lastName: "Doe" }; const b = a.firstName; const c = a.lastName; const d = `${b} ${c}`;
Apabila mengemas kini E, sistem akan mengira semula keseluruhan keadaan, yang membolehkannya mengekalkan satu sumber kebenaran dengan menimpa keadaan sebelumnya.
- Perubahan keadaan berlaku dalam sumber data E!
- Nilai A disebarkan kepada B (pengiraan sumber data B);
- Kemudian, nilai B disebarkan kepada D (pengiraan sumber data D);
- Nilai A disebarkan kepada C (pengiraan sumber data C);
- Nilai E disebarkan kepada C (pengiraan semula sumber data C);.
- Akhir sekali, nilai C disebarkan kepada D (pengiraan semula sumber data D);
Sekali lagi, "Masalah Berlian" berlaku... Kali ini pada sumber data C yang berpotensi dinilai 2 kali, dan sentiasa pada D.
Masalah Berlian
"Masalah Berlian" bukanlah satu cabaran baharu dalam model kereaktifan "bersemangat". Sesetengah algoritma pengiraan (terutamanya yang digunakan oleh MobX) boleh menandai "nod pokok kebergantungan reaktif" untuk meratakan pengiraan keadaan. Dengan pendekatan ini, sistem akan terlebih dahulu menilai sumber data "root" (A dan E dalam contoh kami), kemudian B dan C, dan akhirnya D. Menukar susunan pengiraan keadaan membantu menyelesaikan masalah seperti ini.
TARIK, a.k.a Kereaktifan "Malas".
Model kereaktifan kedua dipanggil "TARIK". Tidak seperti model "PUSH", ia berdasarkan prinsip berikut:
- Pengisytiharan pembolehubah reaktif
- Sistem menangguhkan pengiraan keadaan
- Keadaan terbitan dikira berdasarkan kebergantungannya
- Sistem mengelakkan kemas kini yang berlebihan
Peraturan terakhir inilah yang paling penting untuk diingat: tidak seperti sistem sebelumnya, yang terakhir ini menangguhkan pengiraan keadaan untuk mengelakkan berbilang penilaian sumber data yang sama.
Kes Penggunaan Pertama : Keadaan Awal dan Perubahan Keadaan
Mari kekalkan keadaan awal sebelumnya...
Dalam sistem jenis ini, sintaks keadaan awal akan berada dalam bentuk berikut:
let a = observable.of({ firstName: "John", lastName: "Doe" }); const b = a.pipe(map((a) => a.firstName)); const c = a.pipe(map((a) => a.lastName)); const d = merge(b, c).pipe(reduce((b, c) => `${b} ${c}`));
NB: Peminat reaksi berkemungkinan akan mengenali sintaks ini ?
Mengisytiharkan pembolehubah reaktif memberikan "kelahiran" kepada tuple: pembolehubah tidak berubah pada satu bahagian; kemas kini fungsi pembolehubah ini pada yang lain. Pernyataan selebihnya (B, C dan D dalam kes kami) dianggap sebagai keadaan terbitan kerana ia "mendengar" kebergantungan masing-masing.
d.subscribe((value) => console.log(value));
Ciri yang menentukan sistem "malas" ialah ia tidak menyebarkan perubahan serta-merta, tetapi hanya apabila diminta secara eksplisit.
let a = { firstName: "John", lastName: "Doe" }; const b = a.firstName; const c = a.lastName; const d = `${b} ${c}`;
Dalam model "PULL", menggunakan effect() (daripada komponen) untuk log nilai pembolehubah reaktif (dinyatakan sebagai kebergantungan) mencetuskan pengiraan perubahan keadaan:
- D akan menyemak sama ada kebergantungannya (B dan C) telah dikemas kini;
- B akan menyemak sama ada kebergantungannya (A) telah dikemas kini;
- A akan menyebarkan nilainya kepada B (mengira nilai B);
- C akan menyemak sama ada kebergantungannya (A) telah dikemas kini;
- A akan menyebarkan nilainya kepada C (mengira nilai C)
- B dan C akan menyebarkan nilai masing-masing kepada D (mengira nilai D);
Pengoptimuman sistem ini boleh dilakukan apabila menanyakan kebergantungan. Sesungguhnya, dalam senario di atas, A disoal dua kali untuk menentukan sama ada ia telah dikemas kini. Walau bagaimanapun, pertanyaan pertama mungkin cukup untuk menentukan sama ada keadaan telah berubah. C tidak perlu melakukan tindakan ini... Sebaliknya, A hanya boleh menyiarkan nilainya.
Kes Penggunaan Kedua : Lelaran Seterusnya
Mari kita rumitkan keadaan dengan menambah pembolehubah reaktif kedua "root",
let a = observable.of({ firstName: "John", lastName: "Doe" }); const b = a.pipe(map((a) => a.firstName)); const c = a.pipe(map((a) => a.lastName)); const d = merge(b, c).pipe(reduce((b, c) => `${b} ${c}`));
Sekali lagi, sistem menangguhkan pengiraan keadaan sehingga ia diminta secara eksplisit. Menggunakan kesan yang sama seperti sebelumnya, mengemas kini pembolehubah reaktif baharu akan mencetuskan langkah berikut:
- D akan menyemak sama ada kebergantungannya (B dan C) telah dikemas kini ;
- B akan menyemak sama ada kebergantungannya (A) telah dikemas kini ;
- C akan menyemak sama ada kebergantungannya (A dan E) telah dikemas kini ;
- E akan menyebarkan nilainya kepada C, dan C akan mengambil nilai A melalui memoisasi (mengira nilai C) ;
- C akan menyebarkan nilainya kepada D, dan D akan mengambil nilai B melalui penghafalan (mengira nilai D) ;
Memandangkan nilai A tidak berubah, pengiraan semula pembolehubah ini adalah tidak perlu (perkara yang sama berlaku untuk nilai B). Dalam kes sedemikian, penggunaan algoritma memoisasi meningkatkan prestasi semasa pengiraan keadaan.
TOLAK-TARIK, a.k.a Kereaktifan "Berbutir Halus".
Model kereaktifan terakhir ialah sistem "PUSH-PULL". Istilah "PUSH" mencerminkan penyebaran segera pemberitahuan perubahan, manakala "TARIK" merujuk kepada pengambilan nilai keadaan atas permintaan. Pendekatan ini berkait rapat dengan apa yang dipanggil kereaktifan "berbutir halus", yang mematuhi prinsip berikut:
- Pengisytiharan pembolehubah reaktif (kita bercakap tentang primitif reaktif)
- Pergantungan dijejaki pada tahap atom
- Penyebaran perubahan sangat disasarkan
Perhatikan bahawa kereaktifan jenis ini tidak eksklusif untuk model "PUSH-PULL". Kereaktifan berbutir halus merujuk kepada penjejakan tepat kebergantungan sistem. Jadi, terdapat model kereaktifan PUSH dan PULL yang juga berfungsi dengan cara ini (saya sedang memikirkan Jotai atau Recoil.
Kes Penggunaan Pertama : Keadaan Awal dan Perubahan Keadaan
Masih berdasarkan keadaan awal sebelumnya... Pengisytiharan keadaan awal dalam sistem kereaktifan "berbutir halus" akan kelihatan seperti ini:
let a = { firstName: "John", lastName: "Doe" }; const b = a.firstName; const c = a.lastName; const d = `${b} ${c}`;
NB: Penggunaan kata kunci isyarat bukan sekadar anekdot di sini ?
Dari segi sintaks, ia sangat serupa dengan model "PUSH", tetapi terdapat satu perbezaan yang ketara dan penting: kebergantungan! Dalam sistem kereaktifan "berbutir halus" , tidak perlu mengisytiharkan kebergantungan yang diperlukan secara eksplisit untuk mengira keadaan terbitan, kerana keadaan ini secara tersirat menjejaki pembolehubah yang mereka gunakan. Dalam kes kami, B dan C akan menjejaki perubahan pada nilai A secara automatik dan D akan menjejaki perubahan kepada kedua-dua B dan C.
let a = observable.of({ firstName: "John", lastName: "Doe" }); const b = a.pipe(map((a) => a.firstName)); const c = a.pipe(map((a) => a.lastName)); const d = merge(b, c).pipe(reduce((b, c) => `${b} ${c}`));
Dalam sistem sedemikian, mengemas kini pembolehubah reaktif adalah lebih cekap berbanding model asas "PUSH" kerana perubahan itu disebarkan secara automatik kepada pembolehubah terbitan yang bergantung padanya (hanya sebagai pemberitahuan, bukan nilai itu sendiri).
d.subscribe((value) => console.log(value));
Kemudian, atas permintaan (mari kita ambil contoh logger), penggunaan D dalam sistem akan mengambil nilai keadaan akar yang berkaitan (dalam kes kami A), hitung nilai daripada keadaan terbitan (B dan C), dan akhirnya menilai D. Bukankah ia mod operasi intuitif?
Kes Penggunaan Kedua : Lelaran Seterusnya
Mari kita pertimbangkan keadaan berikut,
a.next({ firstName: "Jane", lastName: "Doe" });
Sekali lagi, aspek "berbutir halus" sistem PUSH-PULL membolehkan pengesanan automatik setiap negeri. Jadi, keadaan terbitan C kini menjejaki keadaan akar A dan E. Mengemas kini pembolehubah E akan mencetuskan tindakan berikut:
- Nyatakan perubahan primitif reaktif E!
- Pemberitahuan perubahan disasarkan (E hingga D melalui C);
- E akan menyebarkan nilainya kepada C, dan C akan mendapatkan semula nilai A melalui memoisasi (mengira nilai C);
- C akan menyebarkan nilainya kepada D, dan D akan mendapatkan semula nilai B melalui memoisasi (mengira nilai D);
Inilah perkaitan terdahulu bagi kebergantungan reaktif antara satu sama lain yang menjadikan model ini begitu cekap!
Sememangnya, dalam sistem "PULL" klasik (seperti DOM Maya React, contohnya), apabila mengemas kini keadaan reaktif daripada komponen, rangka kerja akan dimaklumkan tentang perubahan (mencetuskan " membezakan" fasa). Kemudian, apabila diminta (dan ditangguhkan), rangka kerja akan mengira perubahan dengan merentasi pokok pergantungan reaktif; setiap kali pembolehubah dikemas kini! "Penemuan" keadaan tanggungan ini mempunyai kos yang ketara...
Dengan sistem kereaktifan "berbutir halus" (seperti Isyarat), kemas kini pembolehubah reaktif/primitif secara automatik memberitahu mana-mana keadaan terbitan yang dipautkan kepada mereka tentang perubahan itu. Oleh itu, tidak perlu (semula) menemui kebergantungan yang berkaitan; penyebaran negeri disasarkan!
Kesimpulan(.value)
Pada tahun 2024, kebanyakan rangka kerja web telah memilih untuk memikirkan semula cara ia berfungsi, terutamanya dari segi model kereaktifan mereka. Peralihan ini telah menjadikan mereka secara amnya lebih cekap dan berdaya saing. Yang lain memilih untuk menjadi (masih) hibrid (saya memikirkan tentang Vue di sini), yang menjadikan mereka lebih fleksibel dalam banyak situasi.
Akhir sekali, apa sahaja model yang dipilih, pada pendapat saya, sistem reaktif (baik) dibina berdasarkan beberapa peraturan utama:
- Sistem menghalang keadaan terbitan tidak konsisten;
- Penggunaan keadaan dalam sistem menghasilkan keadaan reaktif;
- Sistem meminimumkan kerja yang berlebihan ;
- Dan, "untuk permulaan keadaan, tidak kira jalan yang ikuti, keputusan akhir sistem akan sentiasa sama! "
Perkara terakhir ini, yang boleh ditafsirkan sebagai prinsip asas pengaturcaraan deklaratif, ialah bagaimana saya melihat sistem reaktif (baik) perlu bersifat deterministik! Inilah "determinisme" yang menjadikan model reaktif boleh dipercayai, boleh diramal dan mudah digunakan dalam projek teknikal pada skala, tanpa mengira kerumitan algoritma.
Atas ialah kandungan terperinci WTF Adakah Kereaktifan !?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Penjelasan terperinci mengenai kaedah penggantian rentetan javascript dan Soalan Lazim Artikel ini akan meneroka dua cara untuk menggantikan watak rentetan dalam JavaScript: Kod JavaScript dalaman dan HTML dalaman untuk laman web. Ganti rentetan di dalam kod JavaScript Cara yang paling langsung ialah menggunakan kaedah pengganti (): str = str.replace ("cari", "ganti"); Kaedah ini hanya menggantikan perlawanan pertama. Untuk menggantikan semua perlawanan, gunakan ungkapan biasa dan tambahkan bendera global g: str = str.replace (/fi

Jadi di sini anda, bersedia untuk mempelajari semua perkara ini yang dipanggil Ajax. Tetapi, apa sebenarnya? Istilah Ajax merujuk kepada kumpulan teknologi longgar yang digunakan untuk membuat kandungan web yang dinamik dan interaktif. Istilah Ajax, yang asalnya dicipta oleh Jesse J

Artikel membincangkan membuat, menerbitkan, dan mengekalkan perpustakaan JavaScript, memberi tumpuan kepada perancangan, pembangunan, ujian, dokumentasi, dan strategi promosi.

Artikel ini membincangkan strategi untuk mengoptimumkan prestasi JavaScript dalam pelayar, memberi tumpuan kepada mengurangkan masa pelaksanaan dan meminimumkan kesan pada kelajuan beban halaman.

Artikel ini membincangkan debugging JavaScript yang berkesan menggunakan alat pemaju pelayar, memberi tumpuan kepada menetapkan titik putus, menggunakan konsol, dan menganalisis prestasi.

Bawa kesan filem matriks ke halaman anda! Ini adalah plugin jQuery yang sejuk berdasarkan filem terkenal "The Matrix". Plugin mensimulasikan kesan aksara hijau klasik dalam filem, dan hanya pilih gambar dan plugin akan mengubahnya menjadi gambar gaya matriks yang diisi dengan aksara angka. Datang dan cuba, sangat menarik! Bagaimana ia berfungsi Plugin memuat imej ke kanvas dan membaca nilai piksel dan warna: data = ctx.getimagedata (x, y, settings.grainsize, settings.grainsize) .data Plugin dengan bijak membaca kawasan segi empat tepat gambar dan menggunakan jQuery untuk mengira warna purata setiap kawasan. Kemudian, gunakan

Artikel ini akan membimbing anda untuk membuat karusel gambar mudah menggunakan perpustakaan jQuery. Kami akan menggunakan perpustakaan BXSlider, yang dibina di atas jQuery dan menyediakan banyak pilihan konfigurasi untuk menubuhkan karusel. Pada masa kini, Gambar Carousel telah menjadi ciri yang mesti ada di laman web - satu gambar lebih baik daripada seribu perkataan! Selepas membuat keputusan untuk menggunakan karusel gambar, soalan seterusnya adalah bagaimana untuk menciptanya. Pertama, anda perlu mengumpul gambar-gambar resolusi tinggi yang berkualiti tinggi. Seterusnya, anda perlu membuat karusel gambar menggunakan HTML dan beberapa kod JavaScript. Terdapat banyak perpustakaan di web yang dapat membantu anda membuat karusel dengan cara yang berbeza. Kami akan menggunakan Perpustakaan BXSlider Sumber Terbuka. Perpustakaan BXSlider menyokong reka bentuk responsif, jadi karusel yang dibina dengan perpustakaan ini dapat disesuaikan dengan mana -mana

Set data sangat penting dalam membina model API dan pelbagai proses perniagaan. Inilah sebabnya mengapa mengimport dan mengeksport CSV adalah fungsi yang sering diperlukan. Dalam tutorial ini, anda akan belajar cara memuat turun dan mengimport fail CSV dalam sudut


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Pelayar Peperiksaan Selamat
Pelayar Peperiksaan Selamat ialah persekitaran pelayar selamat untuk mengambil peperiksaan dalam talian dengan selamat. Perisian ini menukar mana-mana komputer menjadi stesen kerja yang selamat. Ia mengawal akses kepada mana-mana utiliti dan menghalang pelajar daripada menggunakan sumber yang tidak dibenarkan.

ZendStudio 13.5.1 Mac
Persekitaran pembangunan bersepadu PHP yang berkuasa

MinGW - GNU Minimalis untuk Windows
Projek ini dalam proses untuk dipindahkan ke osdn.net/projects/mingw, anda boleh terus mengikuti kami di sana. MinGW: Port Windows asli bagi GNU Compiler Collection (GCC), perpustakaan import yang boleh diedarkan secara bebas dan fail pengepala untuk membina aplikasi Windows asli termasuk sambungan kepada masa jalan MSVC untuk menyokong fungsi C99. Semua perisian MinGW boleh dijalankan pada platform Windows 64-bit.

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

EditPlus versi Cina retak
Saiz kecil, penyerlahan sintaks, tidak menyokong fungsi gesaan kod