$.ajax von jQueryBevor wir beginnen, lassen Sie uns über meine asynchrone JS-Reise sprechen. Als ich noch zur Schule ging, war jQuery noch der König. Die asynchrone Operation, mit der ich in direkten Kontakt kam und die ich am häufigsten verwendete, war die Netzwerkanforderung. Ich verwendete $.ajax, um die Welt zu bereisen, und es begleitete mich von meinem zweiten Studienjahr bis fast ein halbes Jahr nach meinem Abschluss. $.ajax( "/xxx" ) .done(Funktion() { // Erfolg!!! tu etwas ... }) .fail(Funktion() { // Fehlschlag!!! Tu etwas … }) .immer(Funktion() { // Laden abgeschlossen.. }); Es lässt sich nicht leugnen, dass $.ajax ziemlich nützlich ist. In den meisten Szenarien, in denen nur eine Anfrage vorliegt, ist es völlig kompetent und sogar großartig. Es gibt jedoch ein großes Problem, nämlich dass es äußerst ärgerlich ist, wenn man mit einer Anforderungskette konfrontiert wird. Wenn beispielsweise eine Anforderung vom Ergebnis einer anderen Anforderung abhängt, sind zwei möglicherweise nicht wichtig, aber wenn es fünf oder acht sind, möchten Sie möglicherweise Selbstmord begehen. . . $.ajax('/xxx1') .done(Funktion() { // Erfolg!!! tu etwas ... $.ajax('/xxx2') .done(Funktion() { // Erfolg!!! tu etwas ... $.ajax('/xxx3') .done(Funktion() { // Erfolg!!! tu etwas ... $.ajax('/xxx4') .done(Funktion() { // Erfolg!!! tu etwas ... $.ajax('/xxx5') .done(Funktion() { // Erfolg!!! tu etwas ... // mehr... }) .fail(Funktion() { // Fehlschlag!!! Tu etwas … }) .immer(Funktion() { // Laden abgeschlossen.. }); }) .fail(Funktion() { // Fehlschlag!!! Tu etwas … }) .immer(Funktion() { // Laden abgeschlossen.. }); }) .fail(Funktion() { // Fehlschlag!!! Tu etwas … $.ajax('/xxx6') .done(Funktion() { // Erfolg!!! tu etwas ... $.ajax('/xxx7') .done(Funktion() { // Erfolg!!! tu etwas ... // mehr.... }) .fail(Funktion() { // Fehlschlag!!! Tu etwas … }) .immer(Funktion() { // Laden abgeschlossen.. }); }) .fail(Funktion() { // Fehlschlag!!! Tu etwas … }) .immer(Funktion() { // Laden abgeschlossen.. }); }) .immer(Funktion() { // Laden abgeschlossen.. }); }) .fail(Funktion() { // Fehlschlag!!! Tu etwas … }) .immer(Funktion() { // Laden abgeschlossen.. }); }) .fail(Funktion() { // Fehlschlag!!! Tu etwas … }) .immer(Funktion() { // Laden abgeschlossen.. }); Entschuldigung, ich wusste nicht, dass man es so oft schichten kann. . . , aber Tatsache ist, dass solche Prozesse bei TM häufig vorkommen. Sagen Sie mir, dafür kann man doch nicht das Produkt verantwortlich machen, oder? ? ? Ich kann nur mir selbst die Schuld dafür geben, dass ich nicht gut im Lernen bin Ich glaube, dass Kettenoperationen wie diese jeden frustrieren würden. Von der Lesbarkeit des Codes wollen wir erst gar nicht reden. Nehmen wir die Produktanforderungen, die sich jeden Tag ändern. Vielleicht folgten auf Anfrage 1 Anfrage 2 und Anfrage 3. Später entschied der Produktmanager, dass der Prozess nicht richtig war, also wurde es Anfrage 2, Anfrage 3 und Anfrage 1. Wie können wir das ändern? Manche Leute fragen sich vielleicht, warum nicht Axios, Await und Async verwendet werden? Es muss erwähnt werden, dass der Projektcode JSP ist und im Jahr 2008 geschrieben wurde. . . . Nachdem ich mehr als ein halbes Jahr daran herumgebastelt hatte, kam es zu einer großen Wende. Die neuen Projekte, die ich schrieb, begannen, auf Vue umzusteigen und verloren etwas an Kompatibilität, und ich legte sofort los. . . Der Beginn der Webpack-ÄraDas neue Projekt ist Vue + Webpack. Ich habe Axios, Await und Async direkt angeordnet. Jetzt ist der Code sehr einfach zu verwenden und es gibt keine verschachtelten N-Codeschichten mehr. const r1 = warte auf „doEtwas1“(); wenn (r1.xxx === 1) { const r2 = warte auf tuEtwas2(r1); const r3 = warte auf „doEtwas3(r2); // mach was... } anders { const r4 = warte auf tuEtwas4(r1); const r5 = warte auf machEtwas5(r4); // mach was... } // mach was... Allerdings gibt es mit dem obigen Code ein Problem: Wenn eine Aufgabe einen Fehler meldet, wird der Code direkt beendet. . . Dies entspricht nicht unseren Erwartungen, also fügen wir try catch hinzu sei r1; versuchen { r1 = warte auf „doEtwas1“(); } fangen (e) { // tu etwas... zurückkehren; } wenn (r1) { wenn (r1.xxx === 1) { sei r2; versuchen { r2 = warte auf „doSomthing2(r1);“ } fangen (e) { // tu etwas... zurückkehren; } wenn (r2) { sei r3; versuchen { r3 = warte auf „doSomthing3(r2);“ } fangen (e) { // tu etwas... zurückkehren; } // tu etwas... } } anders { sei r4; versuchen { r4 = warte auf „doSomthing4(r1);“ } fangen (e) { // tu etwas... zurückkehren; } wenn (r4) { sei r5; versuchen { r5 = warte auf „doSomthing5(r4);“ } fangen (e) { // tu etwas... zurückkehren; } } // tu etwas... } // tu etwas... } ? ? ? Optimiert ist dasselbe wie nicht optimiert. . . An dieser Stelle fragen sich kluge Freunde wahrscheinlich: Was ist das für ein Pfannkuchen? Und die langweiligen Freunde haben bereits angefangen, darüber nachzudenken, wie dieses Problem gelöst werden könnte. . . Ein genauerer Blick auf VersprechenSchauen wir uns die Definition von Promise an /** * Stellt den Abschluss einer asynchronen Operation dar */ Schnittstelle Promise<T> { /** * Fügt Rückrufe für die Lösung und/oder Ablehnung des Versprechens an. * @param onfulfilled Der Rückruf, der ausgeführt werden soll, wenn das Versprechen eingelöst wird. * @param onrejected Der Rückruf, der ausgeführt werden soll, wenn das Versprechen abgelehnt wird. * @returns: Ein Promise für die Ausführung des jeweils ausgeführten Rückrufs. */ dann <TResult1 = T, TResult2 = nie> (nicht erfüllt?: ((Wert: T) => TResult1 | PromiseLike<TResult1>) | undefiniert | null, nicht abgelehnt?: ((Grund: beliebig) => TResult2 | PromiseLike<TResult2>) | undefiniert | null): Promise<TResult1 | TResult2>; /** * Fügt einen Rückruf nur für die Ablehnung des Versprechens an. * @param onrejected Der Rückruf, der ausgeführt werden soll, wenn das Versprechen abgelehnt wird. * @returns Ein Promise für die Fertigstellung des Rückrufs. */ catch<TResult = nie>(bei Ablehnung?: ((Grund: beliebig) => TResult | PromiseLike<TResult>) | nicht definiert | null): Promise<T | TResult>; } „Dann“ und „catch“ geben beide ein neues Promise zurück. Ich glaube, viele von Ihnen haben bereits herausgefunden, wie man dieses Problem löst. Wir müssen „try catch“ verwenden, da dies einen Fehler meldet. Warum geben wir also nicht einfach ein Ergebnis zurück, das niemals einen Fehler meldet? Tun Sie es einfach Verschachtelung vermeidenFunktion any(Versprechen) { gibt Versprechen zurück. Dann((v) => v).catch((_) => null); } Ist das vollständig gelöst? ? ? Durch Beurteilen, ob ein Wert vorhanden ist, um zu bestimmen, ob es erfolgreich ist, muss kein Try-Catch geschrieben werden, aber ein solcher Code ist etwas schwierig zu verwenden. Wenn dann ein void zurückgegeben wird, ist es fertig. Einer ist undefiniert und der andere ist null. Es ist sinnlos, zu urteilen. Lasst es uns verbessern. Funktion any(Versprechen) { Rückgabeversprechen .then((v) => ({ ok: v, hasErr: false })) .catch((e) => ({ err: e, hasErr: true })); } Verwenden Sie Wörter const r = warte auf irgendetwas(tu etwas()); wenn (r.hasErr) { Konsole.log(r.err); zurückkehren; } Konsole.log(r.ok); Sieht es jetzt nicht perfekt aus? Dann machen wir gleich bei unseren Freunden Werbung dafür. Freund:? ? ? Was ist das für ein Pfannkuchen? Den brauche ich nicht. Ich: Ich habe das geschrieben. Es funktioniert sehr gut in asynchronen Umgebungen. Es ist nicht nötig, Try Catch oder ähnliches zu verschachteln. . . Freund: Okay, ich werde es das nächste Mal verwenden. Jeder kennt sicher schon eine solche Situation: Jeder sieht auf den Code des anderen herab, und solange es sich nicht um eine Bibliothek eines Drittanbieters handelt, verwendet ihn nach Möglichkeit keiner. . . warte auf jsIch dachte, ich wäre der Einzige, der diese Eleganz zu schätzen weiß. Die Dinge nahmen eine Wendung zum Besseren. Eines Tages durchsuchte ich GitHub und fand etwas Ähnliches wie meines, await-to-js. Ein paar Zeilen Code offenbarten die gleiche Besessenheit wie ich. // Unten ist der neuste Code/** * @param { Versprechen } Versprechen * @param { Object= } errorExt – Zusätzliche Informationen, die Sie an das err-Objekt übergeben können * @return { Versprechen } */ Exportfunktion nach <T, U = Fehler> ( Versprechen: Versprechen<T>, errorExt?: Objekt ): Versprechen<[U, undefiniert] | [null, T]> { Rückgabeversprechen .then<[null, T]>((Daten: T) => [null, Daten]) .catch<[U, undefiniert]>((err: U) => { wenn (FehlerExt) { Objekt.assign(err, errorExt); } return [err, undefiniert]; }); } Standardmäßig exportieren nach; Fügen Sie dann das Anwendungsbeispiel ein importieren nach von „await-to-js“; // Wenn Sie CommonJS verwenden (also eine NodeJS-Umgebung), sollte es lauten: // const bis = erfordern ('await-to-js').default; asynchrone Funktion asyncTaskWithCb(cb) { let err, Benutzer, gespeicherteAufgabe, Benachrichtigung; [ err, Benutzer ] = warte auf(UserModel.findById(1)); if(!user) return cb('Kein Benutzer gefunden'); [ err, gespeicherteAufgabe ] = warte auf(TaskModel({userId: user.id, name: 'Demo Task'})); if(err) return cb('Beim Speichern der Aufgabe ist ein Fehler aufgetreten'); if(user.notificationsEnabled) { [ err ] = warte auf (NotificationService.sendNotification (user.id, 'Task erstellt')); if(err) return cb('Fehler beim Senden der Benachrichtigung'); } wenn(savedTask.assignedUser.id !== user.id) { [ err, notification ] = warte auf (NotificationService.sendNotification(savedTask.assignedUser.id, 'Aufgabe wurde für Sie erstellt')); if(err) return cb('Fehler beim Senden der Benachrichtigung'); } cb(null, gespeicherteAufgabe); } asynchrone Funktion asyncFunctionWithThrow() { const [err, Benutzer] = warte auf (UserModel.findById(1)); if (!user) throw new Error('Benutzer nicht gefunden'); } Kommt das Gefühl zurück, nicht länger verschachtelt zu sein? . . Damit meine Freunde die vorherige Codezeile verwenden können, kann ich await-to-js nur widerwillig empfehlen und es auf github posten. Meine Freunde: mehr als 800 Sterne (ps: jetzt 2K+) Die Qualität ist zuverlässig. Ich habe mir die Beispiele angesehen. Nun, es ist sehr gut und perfekt. Ich werde zum nächsten zurückkehren. . . Was dann passierte, muss ich wohl nicht mehr groß erzählen. Auch meinen eigenen Code habe ich komplett durch await-to-js ersetzt. . . Ich behandle die Welt wie meine erste Liebe, aber meine erste Liebe verletzt mich tausendmal ZusammenfassenDie von mir implementierte Version hat tatsächlich einige Probleme. Wenn ich in einer flexiblen Sprache wie JS den Rückgabewert ändere, können andere einfach meine Version kopieren. Der Typ ist nicht streng genug. Wenn er in TS eingefügt wird, kann man nur sagen, dass es ein kleines Problem ist. Das neu hinzugefügte ok, err, hasErr fügt einen kleinen Fall hinzu, ist aber nicht fatal. Die kleine Designphilosophie in await-to-js, warum der Fehler statt des Erfolgs an die erste Stelle des Arrays gesetzt wird, ist sehr klar: Erinnere dich immer an die Fehler, setze die Fehler an die erste Stelle, statt auf den Erfolg zu vertrauen und den Schmerz der Fehler zu vergessen. const [, Ergebnis] = warte auf(iWillSucceed()); Verweise
Dies ist das Ende dieses Artikels über die elegante Verwendung von async await in JS. Weitere Informationen zur eleganten Verwendung von async await in JS finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen! Das könnte Sie auch interessieren:
|
<<: Was ist ein MySQL-Tablespace?
[mysql] Ersetzungsverwendung (Teil des Inhalts ei...
Virtuelle Maschinen sind eine sehr praktische Tes...
In diesem Artikel wird hauptsächlich das Vue-Proj...
Die Installation des RPM-Pakets ist relativ einfa...
Inhaltsverzeichnis 1. Datenbankübersicht 1.1 Entw...
In diesem System steht das #-Zeichen für den Root...
Nach der Installation von Navicat Der folgende Fe...
Die Fähigkeiten, die Front-End-Entwickler beherrs...
1. Bereiten Sie sich im Voraus vor Zu Ihrer Beque...
Informationen zur Überprüfung der Kennwortstärke:...
Ergebnisse erzielenImplementierungscode html <...
1. Zwei Arten der DMA-Zuordnung 1.1. Konsistente ...
Inhaltsverzeichnis 1. Listendurchlauf 2. Die Roll...
Heute haben wir ein weiteres typisches Problem im...
Go ist eine Open-Source-Programmiersprache, die d...