suchen
HeimWeb-Frontendjs-TutorialWTF ist Reaktivität!?

WTF ist Reaktivität!?

Dec 22, 2024 am 05:44 AM

Reaktivitätsmodelle erklärt

Vorwort

Es ist (schon) 10 Jahre her, seit ich mit der Entwicklung von Anwendungen und Websites begonnen habe, aber das JavaScript-Ökosystem war noch nie so spannend wie heute!

Im Jahr 2022 war die Community vom Konzept „Signal“ so fasziniert, dass die meisten JavaScript-Frameworks sie in ihre eigene Engine integrierten. Ich denke an Preact, das seit September 2022 vom Komponentenlebenszyklus entkoppelte reaktive Variablen anbietet; oder in jüngerer Zeit Angular, das Signale im Mai 2023 experimentell implementierte, dann offiziell ab Version 18. Auch andere JavaScript-Bibliotheken haben beschlossen, ihren Ansatz zu überdenken...

Von 2023 bis heute habe ich Signale konsequent in verschiedenen Projekten verwendet. Ihre einfache Implementierung und Nutzung hat mich voll und ganz überzeugt, sodass ich ihre Vorteile in technischen Workshops, Schulungen und Konferenzen mit meinem beruflichen Netzwerk geteilt habe.

Aber in letzter Zeit begann ich mich zu fragen, ob dieses Konzept wirklich „revolutionär“ war/ob es Alternativen zu Signals gibt? Also habe ich mich eingehender mit dieser Überlegung befasst und verschiedene Ansätze für reaktive Systeme entdeckt.

Dieser Beitrag gibt einen Überblick über verschiedene Reaktivitätsmodelle und mein Verständnis ihrer Funktionsweise.

Hinweis: An dieser Stelle, Sie haben es wahrscheinlich erraten, werde ich nicht über Javas „Reaktive Streams“ sprechen; andernfalls hätte ich diesen Beitrag mit „WTF ist Gegendruck!?“ betitelt. ?

Theorie

Wenn wir über Reaktivitätsmodelle sprechen, sprechen wir (in erster Linie) von „reaktiver Programmierung“, insbesondere aber von „Reaktivität“.

Die reaktive Programmierung ist ein Entwicklungsparadigma, das es ermöglicht, die Änderung einer Datenquelle automatisch an Verbraucher weiterzugeben.

Also können wir die Reaktivität als die Fähigkeit definieren, Abhängigkeiten in Echtzeit abhängig von der Datenänderung zu aktualisieren.

Hinweis: Kurz gesagt, wenn ein Benutzer ein Formular ausfüllt und/oder absendet, müssen wir auf diese Änderungen reagieren, eine Ladekomponente oder irgendetwas anderes anzeigen, das angibt, dass etwas passiert. .. Ein weiteres Beispiel: Beim asynchronen Empfang von Daten müssen wir reagieren, indem wir alle oder einen Teil dieser Daten anzeigen, eine neue Aktion ausführen usw.

In diesem Zusammenhang stellen reaktive Bibliotheken Variablen bereit, die automatisch aktualisiert und effizient weitergegeben werden, wodurch es einfacher wird, einfachen und optimierten Code zu schreiben.

Um effizient zu sein, müssen diese Systeme diese Variablen genau dann neu berechnen/auswerten, wenn sich ihre Werte geändert haben! Um sicherzustellen, dass die übertragenen Daten konsistent und aktuell bleiben, muss das System die Anzeige von Zwischenzuständen vermeiden (insbesondere während der Berechnung von Zustandsänderungen).

Hinweis: Der Status bezieht sich auf die Daten/Werte, die während der gesamten Lebensdauer eines Programms/einer Anwendung verwendet werden.

Okay, aber dann... Was genau sind diese „Reaktivitätsmodelle“?

PUSH, auch bekannt als „Eager“ Reaktivität

Das erste Reaktivitätsmodell heißt „PUSH“ (oder „eifrige“ Reaktivität). Dieses System basiert auf den folgenden Prinzipien:

  • Initialisierung von Datenquellen (bekannt als „Observables“)
  • Komponenten/Funktionen abonnieren diese Datenquellen (das sind die Verbraucher)
  • Wenn sich ein Wert ändert, werden die Daten sofort an die Verbraucher (sogenannte „Beobachter“) weitergegeben

Wie Sie vielleicht schon erraten haben, basiert das „PUSH“-Modell auf dem Designmuster „Observable/Observer“.

1. Anwendungsfall: Anfangszustand und Zustandsänderung

Betrachten wir den folgenden Ausgangszustand

let a = { firstName: "John", lastName: "Doe" };
const b = a.firstName;
const c = a.lastName;
const d = `${b} ${c}`;

WTF Is Reactivity !?

Bei Verwendung einer reaktiven Bibliothek (wie RxJS) würde dieser Anfangszustand eher so aussehen:

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}`));

Hinweis: Für diesen Beitrag sollten alle Codeschnipsel als „Pseudocode“ betrachtet werden.

Nehmen wir nun an, dass ein Verbraucher (zum Beispiel eine Komponente) den Wert von Zustand D protokollieren möchte, wann immer diese Datenquelle aktualisiert wird,

d.subscribe((value) => console.log(value));

Unsere Komponente würde den Datenstrom abonnieren; es muss noch eine Veränderung auslösen,

a.next({ firstName: "Jane", lastName: "Doe" });

Von dort aus erkennt das „PUSH“-System die Änderung und sendet sie automatisch an die Verbraucher. Basierend auf dem oben genannten Ausgangszustand finden Sie hier eine Beschreibung der Vorgänge, die auftreten können:

  • Zustandsänderung tritt in Datenquelle A auf!
  • Der Wert von A wird an B weitergegeben (Berechnung der Datenquelle B);
  • Dann wird der Wert von B an D weitergegeben (Berechnung der Datenquelle D);
  • Der Wert von A wird an C weitergegeben (Berechnung der Datenquelle C);
  • Schließlich wird der Wert von C an D weitergegeben (Neuberechnung der Datenquelle D);

WTF Is Reactivity !?

Eine der Herausforderungen dieses Systems liegt in der Reihenfolge der Berechnungen. Basierend auf unserem Anwendungsfall werden Sie tatsächlich feststellen, dass D möglicherweise zweimal ausgewertet wird: ein erstes Mal mit dem Wert von C in seinem vorherigen Zustand; und ein zweites Mal mit dem aktuellen C-Wert! In dieser Art von Reaktivitätsmodell wird diese Herausforderung als „Diamantproblem“ ♦️ bezeichnet.

2. Anwendungsfall: Nächste Iteration

Nehmen wir nun an, dass sich der Staat auf zwei Hauptdatenquellen verlässt,

let a = { firstName: "John", lastName: "Doe" };
const b = a.firstName;
const c = a.lastName;
const d = `${b} ${c}`;

Beim Aktualisieren von E berechnet das System den gesamten Status neu, wodurch eine einzige Quelle der Wahrheit erhalten bleibt, indem der vorherige Status überschrieben wird.

  • Zustandsänderung tritt in Datenquelle E auf!
  • Der Wert von A wird an B weitergegeben (Berechnung der Datenquelle B);
  • Dann wird der Wert von B an D weitergegeben (Berechnung der Datenquelle D);
  • Der Wert von A wird an C weitergegeben (Berechnung der Datenquelle C);
  • Der Wert von E wird an C weitergegeben (Neuberechnung der Datenquelle C);.
  • Schließlich wird der Wert von C an D weitergegeben (Neuberechnung der Datenquelle D);

WTF Is Reactivity !?

Wieder einmal tritt das „Diamantproblem“ auf... Dieses Mal auf der Datenquelle C, die möglicherweise zweimal ausgewertet wird, und zwar immer auf D.

Diamantproblem

Das „Diamantenproblem“ ist keine neue Herausforderung im „eifrigen“ Reaktivitätsmodell. Einige Berechnungsalgorithmen (insbesondere die von MobX verwendeten) können die „Knoten des reaktiven Abhängigkeitsbaums“ markieren, um die Zustandsberechnung auszugleichen. Bei diesem Ansatz würde das System zuerst die „Root“-Datenquellen (A und E in unserem Beispiel), dann B und C und schließlich D auswerten. Eine Änderung der Reihenfolge der Zustandsberechnungen hilft, diese Art von Problem zu beheben.

WTF Is Reactivity !?

PULL, auch bekannt als „faule“ Reaktivität

Das zweite Reaktivitätsmodell heißt "PULL". Im Gegensatz zum „PUSH“-Modell basiert es auf den folgenden Prinzipien:

  • Deklaration reaktiver Variablen
  • Das System verschiebt die Zustandsberechnung
  • Der abgeleitete Status wird basierend auf seinen Abhängigkeiten berechnet
  • Das System vermeidet übermäßige Aktualisierungen

Diese letzte Regel ist am wichtigsten, die Sie sich merken sollten: Im Gegensatz zum vorherigen System verschiebt diese letzte Regel die Zustandsberechnung, um mehrere Auswertungen derselben Datenquelle zu vermeiden.

1. Anwendungsfall: Anfangszustand und Zustandsänderung

Behalten wir den vorherigen Ausgangszustand bei...

WTF Is Reactivity !?

In einem solchen System hätte die Anfangszustandssyntax die folgende Form:

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}`));

Hinweis:React-Enthusiasten werden diese Syntax wahrscheinlich erkennen ?

Durch die Deklaration einer reaktiven Variablen entsteht ein Tupel: unveränderliche Variable auf der einen Seite; Aktualisierungsfunktion dieser Variablen andererseits. Die übrigen Anweisungen (in unserem Fall B, C und D) werden als abgeleitete Zustände betrachtet, da sie auf ihre jeweiligen Abhängigkeiten „lauschen“.

d.subscribe((value) => console.log(value));

Das entscheidende Merkmal eines „faulen“ Systems ist, dass es Änderungen nicht sofort weitergibt, sondern nur, wenn dies ausdrücklich angefordert wird.

let a = { firstName: "John", lastName: "Doe" };
const b = a.firstName;
const c = a.lastName;
const d = `${b} ${c}`;

In einem „PULL“-Modell löst die Verwendung eines effect() (von einer Komponente) zum Protokollieren des Werts einer reaktiven Variablen (angegeben als Abhängigkeit) die Berechnung der Zustandsänderung aus:

  • D prüft, ob seine Abhängigkeiten (B und C) aktualisiert wurden;
  • B prüft, ob seine Abhängigkeit (A) aktualisiert wurde;
  • A gibt seinen Wert an B weiter (wobei der Wert von B berechnet wird);
  • C prüft, ob seine Abhängigkeit (A) aktualisiert wurde;
  • A gibt seinen Wert an C weiter (wobei der Wert von C berechnet wird)
  • B und C geben ihren jeweiligen Wert an D weiter (wobei der Wert von D berechnet wird);

WTF Is Reactivity !?

Eine Optimierung dieses Systems ist bei der Abfrage von Abhängigkeiten möglich. Tatsächlich wird A im obigen Szenario zweimal abgefragt, um festzustellen, ob es aktualisiert wurde. Die erste Abfrage könnte jedoch ausreichen, um festzustellen, ob sich der Status geändert hat. C müsste diese Aktion nicht ausführen... Stattdessen könnte A nur seinen Wert senden.

2. Anwendungsfall: Nächste Iteration

Komplizieren wir den Zustand etwas, indem wir eine zweite reaktive Variable „root“ hinzufügen.

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}`));

Noch einmal verschiebt das System die Zustandsberechnung, bis sie explizit angefordert wird. Mit dem gleichen Effekt wie zuvor löst das Aktualisieren einer neuen reaktiven Variablen die folgenden Schritte aus:

  • D prüft, ob seine Abhängigkeiten (B und C) aktualisiert wurden ;
  • B prüft, ob seine Abhängigkeit (A) aktualisiert wurde ;
  • C prüft, ob seine Abhängigkeiten (A und E) aktualisiert wurden ;
  • E gibt seinen Wert an C weiter und C ruft den Wert von A durch Memoisierung ab (Berechnung des Werts von C) ;
  • C gibt seinen Wert an D weiter und D ruft den Wert von B durch Memoisierung ab (Berechnung des Werts von D) ;

WTF Is Reactivity !?

Da sich der Wert von A nicht geändert hat, ist eine Neuberechnung dieser Variablen nicht erforderlich (dasselbe gilt für den Wert von B). In solchen Fällen verbessert die Verwendung von Memoisierungsalgorithmen die Leistung während der Zustandsberechnung.

PUSH-PULL, auch bekannt als „feinkörnige“ Reaktivität

Das letzte Reaktivitätsmodell ist das „PUSH-PULL“-System. Der Begriff „PUSH“ spiegelt die sofortige Weitergabe von Änderungsbenachrichtigungen wider, während „PULL“ sich auf das Abrufen der Statuswerte bei Bedarf bezieht. Dieser Ansatz steht in engem Zusammenhang mit der sogenannten „feinkörnigen“ Reaktivität, die den folgenden Prinzipien folgt:

  • Deklaration reaktiver Variablen (wir sprechen von reaktiven Grundelementen)
  • Abhängigkeiten werden auf atomarer Ebene verfolgt
  • Die Verbreitung von Veränderungen erfolgt sehr zielgerichtet

Beachten Sie, dass diese Art der Reaktivität nicht nur beim „PUSH-PULL“-Modell auftritt. Unter feinkörniger Reaktivität versteht man die präzise Verfolgung von Systemabhängigkeiten. Es gibt also PUSH und PULL Reaktivitätsmodelle, die ebenfalls auf diese Weise funktionieren (ich denke an Jotai oder Recoil.

).

1. Anwendungsfall: Anfangszustand und Zustandsänderung

Immer noch basierend auf dem vorherigen Anfangszustand... Die Deklaration eines Anfangszustandes in einem „feinkörnigen“ Reaktivitätssystem würde wie folgt aussehen:

let a = { firstName: "John", lastName: "Doe" };
const b = a.firstName;
const c = a.lastName;
const d = `${b} ${c}`;

Hinweis: Die Verwendung des Signalschlüsselworts ist hier nicht nur anekdotisch ?

In Bezug auf die Syntax ist es dem „PUSH“-Modell sehr ähnlich, es gibt jedoch einen bemerkenswerten und wichtigen Unterschied: Abhängigkeiten! In einem „feinkörnigen“ Reaktivitätssystem ist es nicht notwendig, die zur Berechnung eines abgeleiteten Zustands erforderlichen Abhängigkeiten explizit zu deklarieren, da diese Zustände implizit die von ihnen verwendeten Variablen verfolgen. In unserem Fall verfolgen B und C automatisch Änderungen am Wert von A und D verfolgt Änderungen sowohl an B als auch an 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}`));

In einem solchen System ist die Aktualisierung einer reaktiven Variablen effizienter als in einem einfachen „PUSH“-Modell, da die Änderung automatisch an die davon abhängigen abgeleiteten Variablen weitergegeben wird (nur als Benachrichtigung, nicht). der Wert selbst).

d.subscribe((value) => console.log(value));

Dann werden bei Bedarf (nehmen wir das Beispiel Logger) durch die Verwendung von D innerhalb des Systems die Werte der zugehörigen Wurzelzustände (in unserem Fall A) abgerufen und die Werte berechnet ​der abgeleiteten Zustände (B und C) und schließlich D auswerten. Ist das nicht eine intuitive Funktionsweise?

WTF Is Reactivity !?

2. Anwendungsfall: Nächste Iteration

Betrachten wir den folgenden Zustand:

a.next({ firstName: "Jane", lastName: "Doe" });

Auch hier ermöglicht der „feinkörnige“ Aspekt des PUSH-PULL-Systems die automatische Verfolgung jedes Zustands. Der abgeleitete Zustand C verfolgt nun die Wurzelzustände A und E. Durch das Aktualisieren der Variablen E werden die folgenden Aktionen ausgelöst:

  • Zustandsänderung des reaktiven Primitivs E!
  • Gezielte Änderungsbenachrichtigung (E nach D über C);
  • E gibt seinen Wert an C weiter und C ruft den Wert von A durch Memoisierung ab (Berechnung des Werts von C);
  • C gibt seinen Wert an D weiter und D ruft den Wert von B durch Memoisierung ab (Berechnung des Werts von D);

WTF Is Reactivity !?

Dies ist die vorherige Verknüpfung reaktiver Abhängigkeiten miteinander, die dieses Modell so effizient macht!

Tatsächlich wird das Framework in einem klassischen „PULL“-System (wie z. B. dem Virtual DOM von React) beim Aktualisieren eines reaktiven Status von einer Komponente über die Änderung benachrichtigt (wodurch ein „ diffing"-Phase). Dann berechnet das Framework bei Bedarf (und verzögert) die Änderungen, indem es den reaktiven Abhängigkeitsbaum durchläuft. jedes Mal, wenn eine Variable aktualisiert wird! Diese „Entdeckung“ des Zustands der Abhängigkeiten ist mit erheblichen Kosten verbunden...

Bei einem „feinkörnigen“ Reaktivitätssystem (wie Signalen) benachrichtigt die Aktualisierung reaktiver Variablen/Primitive automatisch jeden damit verknüpften abgeleiteten Zustand über die Änderung. Daher besteht keine Notwendigkeit, die damit verbundenen Abhängigkeiten (wieder) zu entdecken; Die Staatsverbreitung ist gezielt!

Fazit(.value)

Im Jahr 2024 haben sich die meisten Web-Frameworks entschieden, ihre Funktionsweise zu überdenken, insbesondere im Hinblick auf ihr Reaktivitätsmodell. Dieser Wandel hat sie im Allgemeinen effizienter und wettbewerbsfähiger gemacht. Andere entscheiden sich dafür, (noch) hybrid zu sein (ich denke hier an Vue), was sie in vielen Situationen flexibler macht.

Abschließend, unabhängig vom gewählten Modell, basiert meiner Meinung nach ein (gutes) reaktives System auf ein paar Hauptregeln:

  1. Das System verhindert inkonsistente abgeleitete Zustände;
  2. Die Verwendung eines Zustands innerhalb des Systems führt zu einem reaktiv abgeleiteten Zustand;
  3. Das System minimiert übermäßige Arbeit ;
  4. Und: „Für einen gegebenen anfänglichen Zustand wird das Endergebnis des Systems immer dasselbe sein, ganz gleich, welchem ​​Weg der Zustand folgt! „

Dieser letzte Punkt, der als grundlegendes Prinzip der deklarativen Programmierung interpretiert werden kann, ist, dass ein (gutes) reaktives System meiner Meinung nach deterministisch sein muss! Dies ist der „Determinismus“, der ein reaktives Modell unabhängig von der Komplexität des Algorithmus zuverlässig, vorhersehbar und einfach in technischen Projekten im großen Maßstab einsetzbar macht.

Das obige ist der detaillierte Inhalt vonWTF ist Reaktivität!?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
JavaScript und das Web: Kernfunktionalität und AnwendungsfälleJavaScript und das Web: Kernfunktionalität und AnwendungsfälleApr 18, 2025 am 12:19 AM

Zu den Hauptanwendungen von JavaScript in der Webentwicklung gehören die Interaktion der Clients, die Formüberprüfung und die asynchrone Kommunikation. 1) Dynamisches Inhaltsaktualisierung und Benutzerinteraktion durch DOM -Operationen; 2) Die Kundenüberprüfung erfolgt vor dem Einreichung von Daten, um die Benutzererfahrung zu verbessern. 3) Die Aktualisierung der Kommunikation mit dem Server wird durch AJAX -Technologie erreicht.

Verständnis der JavaScript -Engine: ImplementierungsdetailsVerständnis der JavaScript -Engine: ImplementierungsdetailsApr 17, 2025 am 12:05 AM

Es ist für Entwickler wichtig, zu verstehen, wie die JavaScript -Engine intern funktioniert, da sie effizientere Code schreibt und Leistungs Engpässe und Optimierungsstrategien verstehen kann. 1) Der Workflow der Engine umfasst drei Phasen: Parsen, Kompilieren und Ausführung; 2) Während des Ausführungsprozesses führt die Engine dynamische Optimierung durch, wie z. B. Inline -Cache und versteckte Klassen. 3) Zu Best Practices gehören die Vermeidung globaler Variablen, die Optimierung von Schleifen, die Verwendung von const und lass und die Vermeidung übermäßiger Verwendung von Schließungen.

Python vs. JavaScript: Die Lernkurve und BenutzerfreundlichkeitPython vs. JavaScript: Die Lernkurve und BenutzerfreundlichkeitApr 16, 2025 am 12:12 AM

Python eignet sich besser für Anfänger mit einer reibungslosen Lernkurve und einer kurzen Syntax. JavaScript ist für die Front-End-Entwicklung mit einer steilen Lernkurve und einer flexiblen Syntax geeignet. 1. Python-Syntax ist intuitiv und für die Entwicklung von Datenwissenschaften und Back-End-Entwicklung geeignet. 2. JavaScript ist flexibel und in Front-End- und serverseitiger Programmierung weit verbreitet.

Python gegen JavaScript: Community, Bibliotheken und RessourcenPython gegen JavaScript: Community, Bibliotheken und RessourcenApr 15, 2025 am 12:16 AM

Python und JavaScript haben ihre eigenen Vor- und Nachteile in Bezug auf Gemeinschaft, Bibliotheken und Ressourcen. 1) Die Python-Community ist freundlich und für Anfänger geeignet, aber die Front-End-Entwicklungsressourcen sind nicht so reich wie JavaScript. 2) Python ist leistungsstark in Bibliotheken für Datenwissenschaft und maschinelles Lernen, während JavaScript in Bibliotheken und Front-End-Entwicklungsbibliotheken und Frameworks besser ist. 3) Beide haben reichhaltige Lernressourcen, aber Python eignet sich zum Beginn der offiziellen Dokumente, während JavaScript mit Mdnwebdocs besser ist. Die Wahl sollte auf Projektbedürfnissen und persönlichen Interessen beruhen.

Von C/C nach JavaScript: Wie alles funktioniertVon C/C nach JavaScript: Wie alles funktioniertApr 14, 2025 am 12:05 AM

Die Verschiebung von C/C zu JavaScript erfordert die Anpassung an dynamische Typisierung, Müllsammlung und asynchrone Programmierung. 1) C/C ist eine statisch typisierte Sprache, die eine manuelle Speicherverwaltung erfordert, während JavaScript dynamisch eingegeben und die Müllsammlung automatisch verarbeitet wird. 2) C/C muss in den Maschinencode kompiliert werden, während JavaScript eine interpretierte Sprache ist. 3) JavaScript führt Konzepte wie Verschlüsse, Prototypketten und Versprechen ein, die die Flexibilität und asynchrone Programmierfunktionen verbessern.

JavaScript -Engines: Implementierungen vergleichenJavaScript -Engines: Implementierungen vergleichenApr 13, 2025 am 12:05 AM

Unterschiedliche JavaScript -Motoren haben unterschiedliche Auswirkungen beim Analysieren und Ausführen von JavaScript -Code, da sich die Implementierungsprinzipien und Optimierungsstrategien jeder Engine unterscheiden. 1. Lexikalanalyse: Quellcode in die lexikalische Einheit umwandeln. 2. Grammatikanalyse: Erzeugen Sie einen abstrakten Syntaxbaum. 3. Optimierung und Kompilierung: Generieren Sie den Maschinencode über den JIT -Compiler. 4. Führen Sie aus: Führen Sie den Maschinencode aus. V8 Engine optimiert durch sofortige Kompilierung und versteckte Klasse.

Jenseits des Browsers: JavaScript in der realen WeltJenseits des Browsers: JavaScript in der realen WeltApr 12, 2025 am 12:06 AM

Zu den Anwendungen von JavaScript in der realen Welt gehören die serverseitige Programmierung, die Entwicklung mobiler Anwendungen und das Internet der Dinge. Die serverseitige Programmierung wird über node.js realisiert, die für die hohe gleichzeitige Anfrageverarbeitung geeignet sind. 2. Die Entwicklung der mobilen Anwendungen erfolgt durch reaktnative und unterstützt die plattformübergreifende Bereitstellung. 3.. Wird für die Steuerung von IoT-Geräten über die Johnny-Five-Bibliothek verwendet, geeignet für Hardware-Interaktion.

Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)Apr 11, 2025 am 08:23 AM

Ich habe eine funktionale SaaS-Anwendung mit mehreren Mandanten (eine EdTech-App) mit Ihrem täglichen Tech-Tool erstellt und Sie können dasselbe tun. Was ist eine SaaS-Anwendung mit mehreren Mietern? Mit Multi-Tenant-SaaS-Anwendungen können Sie mehrere Kunden aus einem Sing bedienen

See all articles

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
1 Monate vorBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
1 Monate vorBy尊渡假赌尊渡假赌尊渡假赌
Will R.E.P.O. Crossplay haben?
1 Monate vorBy尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

Herunterladen der Mac-Version des Atom-Editors

Herunterladen der Mac-Version des Atom-Editors

Der beliebteste Open-Source-Editor

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

DVWA

DVWA

Damn Vulnerable Web App (DVWA) ist eine PHP/MySQL-Webanwendung, die sehr anfällig ist. Seine Hauptziele bestehen darin, Sicherheitsexperten dabei zu helfen, ihre Fähigkeiten und Tools in einem rechtlichen Umfeld zu testen, Webentwicklern dabei zu helfen, den Prozess der Sicherung von Webanwendungen besser zu verstehen, und Lehrern/Schülern dabei zu helfen, in einer Unterrichtsumgebung Webanwendungen zu lehren/lernen Sicherheit. Das Ziel von DVWA besteht darin, einige der häufigsten Web-Schwachstellen über eine einfache und unkomplizierte Benutzeroberfläche mit unterschiedlichen Schwierigkeitsgraden zu üben. Bitte beachten Sie, dass diese Software