Heim > Web-Frontend > js-Tutorial > Asynchronen Operationen in React Redux -Anwendungen

Asynchronen Operationen in React Redux -Anwendungen

Lisa Kudrow
Freigeben: 2025-02-16 12:02:12
Original
495 Leute haben es durchsucht

Async Operations in React Redux Applications

Schlüsselpunkte

  • Die einzelne Thread-Natur von JavaScript bedeutet, dass asynchrone Operationen wie API-Aufrufe für die nicht blockierende UIS von entscheidender Bedeutung sind, und die effiziente Behandlung dieser Operationen ist bei React-Redux-Anwendungen von entscheidender Bedeutung.
  • Redux Thunk, Redux-Saga und Redux-Beobachtungsdienst sind beliebte Redux Asynchronous Operation Management Middleware, die jeweils unterschiedliche Vorteile bieten, die auf der Komplexität und den Anforderungen der Anwendung basieren.
  • Redux Thunk vereinfacht die asynchrone Aktionsverteilung, indem es Rückgabefunktionen anstelle von Aktionen zulässt, wodurch sequentielle API -Aufrufe und Verarbeitung von Daten in diesen Funktionen aktiviert werden.
  • Redux-Saga nutzt die ES6-Generatoren, um leistungsstärkere Lösungen für komplexe Szenarien wie die Handhabung von Rennbedingungen, Pausen und Absagen von Vorgängen bereitzustellen, wodurch es für große Anwendungen geeignet ist.
  • Redux-Beobachter nutzt RXJs, um eine leistungsstarke Möglichkeit zu bieten, Nebenwirkungen durch Aktionsströme zu verwalten, und bieten eine hervorragende Skalierbarkeit und Kontrolle über asynchronen Operationen in komplexen Anwendungsarchitekturen.

Dieser Artikel wurde ursprünglich in Codebrahma veröffentlicht.

JavaScript ist eine Programmiersprache mit einem Thread. Das heißt, wenn Sie den folgenden Code schreiben ...

Async Operations in React Redux Applications

… Die zweite Zeile wird erst nach Ausführung der ersten Zeile ausgeführt. Dies ist in den meisten Fällen kein Problem, da der Client oder Server Millionen von Berechnungen pro Sekunde ausführt. Wir bemerken diese Effekte nur, wenn wir kostspielige Berechnungen durchführen (eine Aufgabe, die eine Weile dauert, um abgeschlossen zu werden -, dauert eine Netzwerkanforderung einige Zeit, um zurückzukehren).

Warum zeige ich hier nur API -Anrufe (Netzwerkanforderungen)? Was ist mit anderen asynchronen Operationen? API -Aufrufe sind ein sehr einfaches und nützliches Beispiel, um zu beschreiben, wie mit asynchronen Operationen umgegangen werden. Es gibt andere Vorgänge, wie setTimeout(), leistungsintensives Computer, Bildbelastung und event-gesteuerte Operationen.

Beim Erstellen einer Anwendung müssen wir überlegen, wie sich die asynchrone Ausführung auf die Struktur auswirkt. Stellen Sie sich beispielsweise fetch() als eine Funktion vor, die einen API -Aufruf (Netzwerkanforderung) aus dem Browser ausführt. (Ignorieren Sie, ob es sich um eine AJAX -Anfrage handelt. Behandle ihr Verhalten einfach als asynchron oder synchron.) Die Zeit, die zu verstrichen ist, wenn die Anforderung auf dem Server verarbeitet wird, tritt nicht auf dem Haupt -Thread auf. Daher wird Ihr JS -Code weiter ausgeführt und sobald die Anforderung eine Antwort zurückgibt, aktualisiert er den Thread.

Betrachten Sie diesen Code:

userId = fetch(userEndPoint); // 从 userEndpoint 获取 userId
userDetails = fetch(userEndpoint, userId) // 为此特定 userId 获取数据。
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

In diesem Fall, da fetch() asynchron ist, werden wir, wenn wir versuchen, userDetails zu erhalten, nicht userId. Wir müssen es also so erstellen, dass die zweite Zeile erst nach der Rückgabe der ersten Zeile die Antwort ausgeführt wird.

Die meisten modernen Implementierungen für Netzwerkanforderungen sind asynchron. Dies funktioniert jedoch nicht immer, da wir uns auf frühere API -Antwortdaten für nachfolgende API -Aufrufe verlassen. Lassen Sie uns sehen, wie Sie es speziell in einer ReactJS/Redux -Anwendung erstellen.

React ist eine Front-End-Bibliothek zum Erstellen von Benutzeroberflächen. Redux ist ein staatlicher Container, der den gesamten Zustand einer Anwendung verwaltet. Durch die Verwendung von React mit Redux können wir effiziente und skalierbare Anwendungen erstellen. In einer solchen Reaktionsanwendung gibt es verschiedene Möglichkeiten, asynchrone Operationen aufzubauen. Für jede Methode werden wir ihre Vor- und Nachteile in Bezug auf die folgenden Faktoren erörtern:

  • Code Clarity
  • Skalierbarkeit
  • Einfach zu handhaben von Fehlern

Für jede Methode werden wir diese beiden API -Aufrufe ausführen:

1. userDetails Angenommen, der Endpunkt ist . Es wird die Stadt in die Antwort einbeziehen. Die Antwort ist ein Objekt:

2. /details Angenommen, der Endpunkt ist

. Die Antwort ist ein Array:
userId = fetch(userEndPoint); // 从 userEndpoint 获取 userId
userDetails = fetch(userEndpoint, userId) // 为此特定 userId 获取数据。
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Denken Sie daran, dass wir nach Abschluss der ersten Anfrage nur die zweite Anfrage stellen können (da dies von der ersten Anfrage abhängt). Schauen wir uns verschiedene Methoden an: Verwenden Sie Versprechen oder asynchron/warten Sie direkt mit

/restuarants/:city Verwenden von Redux Thunk

userDetails: {
  …
  city: 'city',
  …
};
Nach dem Login kopieren
Nach dem Login kopieren
Verwenden von Redux-Saga

Verwenden von Redux Observables
  • setState Ich habe die obigen Methoden ausdrücklich ausgewählt, da sie die am häufigsten verwendeten Methoden in großen Projekten sind. Es gibt noch andere Methoden, die für eine bestimmte Aufgabe spezifischer sind und nicht alle Funktionen haben, die von einer komplexen Anwendung erforderlich sind (z. B.
  • Redux-Async, Redux-Promise, redux-async-queue
  • ).
  • verspricht
  • Versprechen ist ein Objekt, das in Zukunft zu einem bestimmten Zeitpunkt einen einzelnen Wert erzeugen kann: ein analysierter Wert oder eine ungelöste Ursache (zum Beispiel ist ein Netzwerkfehler aufgetreten). - Eric Elliot

In unserem Beispiel werden wir die Axios -Bibliothek verwenden, um die Daten zu erhalten, was ein Versprechen zurückgibt, wenn wir eine Netzwerkanforderung stellen. Das Versprechen kann eine Antwort analysieren und zurückgeben oder einen Fehler machen. Sobald die React -Komponente

montiert ist, können wir es direkt wie folgt bekommen:

Auf diese Weise wird die

-Komponente

die Restaurantliste automatisch neu rendern und lädt die Restaurantliste automatisch erneut.

async/act ist eine neue Implementierung, mit der wir asynchrone Operationen ausführen können. Zum Beispiel kann die gleiche Funktion erreicht werden durch:

Beide Methoden sind am einfachsten. Da sich die gesamte Logik in der Komponente befindet, können wir nach dem Laden der Komponente problemlos alle Daten gleichzeitig abrufen.
['restaurant1', 'restaurant2', …]
Nach dem Login kopieren

Nachteile dieser Methode Das Problem tritt auf, wenn komplexe datenbasierte Interaktionen auftreten. Betrachten Sie beispielsweise die folgende Situation:

Async Operations in React Redux Applications

  • Wir möchten nicht, dass der Thread JS durch Netzwerkanforderungen blockiert wird.
  • Alle oben genannten Situationen machen den Code sehr komplex und schwer zu warten und zu testen.
  • Außerdem ist die Skalierbarkeit ein großes Problem, denn wenn wir den Fluss der Anwendung ändern möchten, müssen wir alle Abrufvorgänge aus der Komponente entfernen.
  • Stellen Sie sich vor, was wir tun würden, wenn die Komponente über dem Eltern-Kind-Baum wäre. Dann müssen wir alle Darstellungskomponenten ändern, die von den Daten abhängen.
  • Beachten Sie auch, dass sich die gesamte Geschäftslogik innerhalb der Komponente befindet.

Wie verbessern wir uns?

  1. Statusverwaltung mit globalem Speicher kann in diesen Fällen die Hälfte unserer Probleme lösen. Wir werden Redux als unseren globalen Speicher verwenden.

  2. Geschäftslogik an den richtigen Ort verschieben, wenn wir in Betracht ziehen, die Geschäftslogik aus der Komponente herauszuholen, wo genau können wir das tun? In Aktionen? In Reduzierern? Durch Middleware? Die Architektur von Redux ist synchron. Sobald Sie eine Aktion (JS -Objekt) verteilen und den Speicher erreicht haben, arbeitet der Reduzierer darauf.

  3. Stellen Sie sicher

Async Operations in React Redux Applications

Daraus können wir erfahren, dass wir die richtige Aktion zum richtigen Zeitpunkt verteilen können, wenn wir alle Erfassungslogik vor dem Reduzierer - d. H. Aktion oder Middleware - bewegen. Sobald der Abruf beginnt, können wir beispielsweise

verteilen, und wenn es fertig ist, können wir dispatch({ type: 'FETCH_STARTED' }) verteilen. dispatch({ type: 'FETCH_SUCCESS' })

Möchten Sie eine React JS -Anwendung entwickeln?

Verwenden von Redux Thunk

Redux Thunk ist eine Middleware für Redux. Es ermöglicht uns im Grunde, Funktionen anstelle von Objekten als Aktion zurückzugeben. Dies hilft, indem

und dispatch als Parameter der Funktion bereitgestellt wird. Wir verwenden getState, um die erforderlichen Aktionen zum richtigen Zeitpunkt zu verteilen. Die Vorteile sind: dispatch

    Ermöglichen Sie mehrere Verteilungen innerhalb der Funktion
  • Die Association of Business Logic mit der Akquisition wird von der React -Komponente zu den Aktionen verschoben.
In unserem Beispiel können wir die Aktion wie folgt umschreiben:

userId = fetch(userEndPoint); // 从 userEndpoint 获取 userId
userDetails = fetch(userEndpoint, userId) // 为此特定 userId 获取数据。
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Wie Sie sehen, haben wir jetzt eine gute Kontrolle darüber, welche Art von Aktion verteilt ist. Jeder Funktionsaufruf (z. B. fetchStarted(), fetchUserDetailsSuccess(), fetchRestaurantsSuccess() und fetchError()) verteilen eine Aktion vom Typ Normales JavaScript -Objekt vom Typ, und bei Bedarf können zusätzliche Details hinzugefügt werden. Jetzt besteht die Aufgabe des Reduzierers darin, jede Aktion zu verarbeiten und die Ansicht zu aktualisieren. Ich habe nicht über Reduzierer gesprochen, weil es von hier aus einfach ist und die Implementierung möglicherweise anders sein kann.

Um diese Funktion zu erledigen, müssen wir die React -Komponente an die Redux anschließen und die Aktion mit der Redux -Bibliothek an die Komponente binden. Sobald wir fertig sind, können wir einfach this.props.getRestaurants() aufrufen, was wiederum alle oben genannten Aufgaben behandelt und die Ansicht gemäß dem Reduzierer aktualisieren.

Für seine Skalierbarkeit kann Redux Thunk für Anwendungen verwendet werden, die keine komplexe Kontrolle asynchroner Aktionen beinhalten. Darüber hinaus funktioniert es nahtlos mit anderen Bibliotheken, wie im folgenden Abschnitt beschrieben.

Es ist jedoch immer noch ein bisschen schwierig, bestimmte Aufgaben mit Redux Thunk auszuführen. Zum Beispiel müssen wir den Zwischenabrufvorgang innehalten oder nur die neuesten Anrufe zulassen, wenn mehrere solche Anrufe vorhanden sind oder wenn andere APIs diese Daten erhalten und wir abbrechen müssen.

Wir können diese immer noch implementieren, aber es wird komplizierter sein, genau auszuführen. Im Vergleich zu anderen Bibliotheken wird die Code -Klarheit komplexer Aufgaben etwas schlechter sein und schwieriger zu pflegen.

Verwenden von Redux-Saga

Mit der Redux-Saga-Middleware können wir den zusätzlichen Vorteil erzielen, um die meisten der oben genannten Funktionen zu beheben. Redux-Saga wird basierend auf dem ES6-Generator entwickelt.

Redux-Saga bietet eine API, die die folgenden Ziele erreicht:

  • Blockieren von Ereignissen, Blockieren von Fäden auf derselben Zeile, bis einige Vorgänge abgeschlossen sind
  • Nicht blockierende Ereignisse, wodurch der Code asynchron ist
  • Bearbeiten Sie den Wettbewerb zwischen mehreren asynchronen Anfragen
  • pause/drosseln/decken Sie jede Aktion
  • ab

Wie funktioniert Saga?

Saga verwendet eine Kombination aus ES6 -Generator und Async/Awit API, um asynchrone Operationen zu vereinfachen. Grundsätzlich arbeitet es an seinen separaten Threads, wo wir mehrere API -Anrufe tätigen können. Wir können ihre API verwenden, um jeden Anruf synchron oder asynchron zu gestalten, abhängig vom Anwendungsfall. Die API bietet die Möglichkeit, einen Thread auf derselben Zeile warten zu lassen, bis die Anforderung eine Antwort zurückgibt. Abgesehen davon bietet diese Bibliothek viele andere APIs, die API -Anfragen sehr einfach zu handhaben.

Betrachten Sie unser vorheriges Beispiel: Wenn wir eine Saga initialisieren und mit Redux basierend auf dem konfigurieren, was in ihrer Dokumentation erwähnt wird, können wir Folgendes tun:

userDetails: {
  …
  city: 'city',
  …
};
Nach dem Login kopieren
Nach dem Login kopieren

Wenn wir es also mit einer einfachen Aktion vom Typ FETCH_RESTAURANTS verteilen, hört die Saga Middleware an und reagiert. Tatsächlich wird keine Aktion von Middleware verwendet. Es hört nur noch einige andere Aufgaben aus und verteilt bei Bedarf neue Aktionen. Durch die Verwendung dieser Architektur können wir mehrere Anforderungen verteilen, von denen jede beschreibt:

  • Wann beginnt die erste Anfrage?
  • Wann wird die erste Anfrage abgeschlossen
  • Wann beginnt die zweite Anfrage?

und so weiter.

Zusätzlich können Sie die Vorteile von fetchRestaurantSaga() sehen. Wir verwenden derzeit die call API, um Blockierungsanrufe zu implementieren. SAGA liefert andere APIs wie fork(), die nicht blockierende Anrufe implementiert. Wir können Blockier- und nicht blockierende Anrufe kombinieren, um eine Struktur aufrechtzuerhalten, die für unsere Anwendung geeignet ist.

Mit Skalierbarkeit ist die Verwendung von SAGA von Vorteil:

  • Wir können Saga basierend auf einer bestimmten Aufgabe erstellen und gruppieren. Wir können eine Saga aus einer anderen Saga auslösen, indem wir einfach eine Aktion verteilen.
  • Da es sich um eine Middleware handelt, wird die Aktion, die wir geschrieben haben, ein normales JS -Objekt sein, im Gegensatz zu Thunk.
  • Da wir die Geschäftslogik in Saga (ein Middleware) einfügen, wäre es viel einfacher, den React -Teil davon zu verstehen, wenn wir wissen, wozu Saga fähig ist.
  • Fehler können einfach überwacht und über den Versuch/Catch -Modus auf Speicherplatz verteilt werden.

Verwenden von Redux-beobserservables

Wie in seiner Dokumentation angegeben, ist "epic der Kernprimitive des Redux-beobachtbaren Abschnitts:

  1. epic ist eine Funktion, die den Aktionsstrom empfängt und den Aktionsstrom zurückgibt. Das heißt, epische läuft parallel zum normalen Redux -Verteilungskanal, nachdem der Reduzierer sie erhalten hat.
  2. Aktion wird immer durch einen Reduzierer durchgeführt, bevor Epic sie empfängt. Epic empfängt und gibt nur einen weiteren Aktionsstrom aus. Dies ähnelt der Redux-Saga, da keine der Aktionen von Middleware verwendet wird. Es hört nur noch einige andere Aufgaben aus und führt zu.

Für unsere Aufgabe können wir einfach den folgenden Code schreiben:

userId = fetch(userEndPoint); // 从 userEndpoint 获取 userId
userDetails = fetch(userEndpoint, userId) // 为此特定 userId 获取数据。
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Zuerst mag dies ein bisschen verwirrend erscheinen. Je mehr Sie RXJs verstehen, desto einfacher ist es, ein Epos zu erstellen.

Wie Saga können wir mehrere Aktionen verteilen, von denen jeder beschreibt, in welchem ​​Teil der API -Anforderungskette sich der Thread derzeit befindet.

In Bezug auf die Skalierbarkeit können wir Epic basierend auf einer bestimmten Aufgabe teilen oder kombinieren. Daher kann diese Bibliothek dazu beitragen, skalierbare Anwendungen aufzubauen. Wenn wir das beobachtbare Muster des Schreibens des Codes verstehen, ist die Code -Klarheit gut.

meine Einstellungen

Wie kann ich bestimmen, welche Bibliothek verwendet werden soll? Es hängt davon ab, wie komplex unsere API -Anfragen sind.

Wie wählen Sie zwischen Redux-Saga und Redux-beobachtbar? Es hängt vom Lerngenerator oder RXJs ab. Beide sind unterschiedliche Konzepte, aber ebenso gut genug. Ich schlage vor, beide zu sehen, welche für Sie besser ist.

Wo ist die Geschäftslogik für die Verarbeitung von APIs? Es ist am besten, es vor den Reduzierer zu stellen, aber nicht in der Komponente. Der beste Weg ist in der Middleware (mit Saga oder Observable).

Sie können mehr React -Entwicklungsartikel bei Codebrahma lesen.

FAQs über asynchrone Operationen in React-Redux-Anwendungen

Welche Rolle spielt Middleware bei der Behandlung asynchroner Operationen in Redux?

Middleware in Redux spielt eine entscheidende Rolle beim Umgang mit asynchronen Operationen. Es bietet einen Erweiterungspunkt von Drittanbietern zwischen der Verteilungsaktion und der Aktion am Reduzierer. Middleware kann verwendet werden, um Aktionen aufzuzeichnen, zu ändern und sogar zu stornieren sowie andere Aktionen zu verteilen. Im Kontext asynchroner Vorgänge ermöglicht Middleware wie Redux Thunk oder Redux -Saga die Aktion Ersteller, die Funktionen anstelle von Aktionen zurückgeben. Diese Funktion kann dann verwendet werden, um die Verteilung einer Aktion zu verzögern oder nur eine Aktion zu verteilen, wenn ein bestimmter Zustand erfüllt ist.

Wie hilft Redux Thunk bei der Verwaltung asynchroner Operationen?

Redux Thunk ist eine Middleware, mit der Sie Action -Ersteller schreiben können, die Funktionen anstelle von Action zurückgeben. Thunk kann verwendet werden, um die Verteilung von Aktionen zu verzögern oder Aktionen zu verteilen, wenn bestimmte Bedingungen erfüllt sind. Diese Funktion macht es zu einem hervorragenden Werkzeug für den Umgang mit asynchronen Operationen in Redux. Sie können beispielsweise eine Aktion verteilen, um den Beginn eines API -Aufrufs anzuzeigen und dann eine andere Aktion zu verteilen, wenn der Anruf Daten oder Fehlermeldungen zurückgibt.

Was ist der Unterschied zwischen Redux Thunk und Redux -Saga?

Redux Thunk und Redux -Saga sind beide Middleware, um Nebenwirkungen in Redux zu verwalten, einschließlich asynchroner Operationen. Der Hauptunterschied zwischen beiden ist ihr Ansatz. Redux Thunk verwendet Callback -Funktionen, um asynchrone Operationen zu verarbeiten, während Redux -Saga Generatorfunktionen und deklarative Methoden verwendet. Dies macht Redux -Saga leistungsfähiger und flexibler, aber auch komplexer. Wenn Ihre Anwendung einfache asynchrone Operationen hat, kann Redux Thunk ausreichen. Für komplexere Szenarien, die Rassenbedingungen, Stornierung und IF-ELSE-Logik beinhalten, ist Redux-Saga jedoch eine bessere Wahl.

Wie kann man Fehler in asynchronen Operationen in Redux umgehen?

Aktion kann verteilt werden, wenn während einer asynchronen Operation ein Fehler auftritt, um die Fehlerbehandlung bei asynchronem Betrieb in Redux zu verarbeiten. Diese Aktion kann ihre Fehlermeldung als Nutzlast aufnehmen. Sie können diese Aktion dann im Reduzierer umgehen, um den Status mit der Fehlermeldung zu aktualisieren. Auf diese Weise kann eine Fehlermeldung an den Benutzer angezeigt oder zum Debuggen aufgezeichnet werden.

Wie testet man asynchrone Aktion in Redux?

asynchrone Aktionen in Redux können getestet werden, indem Redux -Speicher- und API -Aufrufe verspottet werden. Für den Redux -Speicher können Sie Bibliotheken wie redux-mock-store verwenden. Für API -Aufrufe können Sie Bibliotheken wie fetch-mock oder nock verwenden. In Ihren Tests können Sie eine asynchrone Aktion verteilen und dann behaupten, dass die erwartete Aktion mit der richtigen Nutzlast verteilt wurde.

Wie kann man asynchrone Operationen in Redux stornieren?

Middleware wie Redux -Saga kann verwendet werden, um asynchrone Vorgänge in Redux abzubrechen. Redux Saga verwendet Generatorfunktionen, die mit cancel Effekt abgebrochen werden können. Wenn der Effekt cancel Effekt erfolgt, wird die Saga von seinem Startpunkt abgebrochen, bis der aktuelle Effekt aufgehoben ist.

Wie kann man Rennbedingungen in asynchronen Operationen in Redux umgehen?

Middleware wie Redux -Saga kann verwendet werden, um die Rennbedingungen in asynchronen Operationen in Redux zu bewältigen. Redux -Saga liefert Effekte wie takeLatest und takeEvery, mit denen gleichzeitige Aktionen verarbeitet werden können. Wenn beispielsweise die zuvor gestartete Saga -Aufgabe noch ausgeführt wird, wenn eine neue Aktion verteilt wird, storniert takeLatest die Aufgabe.

Wie kann ich mit Redux Thunk Async/Warte verwenden?

Redux Thunk unterstützt nativ asynchron/wartet. In Ihrem Action -Schöpfer können Sie asynchrone Funktionen anstelle von regulären Funktionen zurückgeben. In dieser asynchronen Funktion können Sie Async/Auseit verwenden, um asynchrone Operationen zu verarbeiten. Wenn der asynchrone Vorgang abgeschlossen ist, kann die Funktion dispatch mit dem Aktionsobjekt aufgerufen werden.

Wie kann ich den Ladezustand in asynchronen Operationen in Redux umgehen?

Der Ladestatus in asynchronen Operationen in Redux kann durch Verteilung von Aktionen vor und nach asynchronen Operationen behandelt werden. Die vor dem Vorgang verteilte Aktion kann den Laststatus auf true festlegen und die nach dem Vorgang verteilte Aktion auf false festlegen. In Ihrem Reduzierer können Sie diese Aktionen erledigen, um den Lastzustand im Speicher zu aktualisieren.

Wie kann man mit Nebenwirkungen in Redux umgehen?

Nebenwirkungen in Redux können mit Middleware wie Redux Thunk oder Redux -Saga behandelt werden. Mit dieser Middleware können Sie Action -Ersteller schreiben, die Funktionen anstelle von Aktionen zurückgeben. Diese Funktion kann verwendet werden, um Nebenwirkungen wie asynchrone Operationen, Protokollierung und konditionell verteilte Aktionen durchzuführen.

Das obige ist der detaillierte Inhalt vonAsynchronen Operationen in React Redux -Anwendungen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage