Was ist ein Versprechen?Promise ist eine Lösung für asynchrone Programmierung. Es handelt sich eigentlich um einen Konstruktor mit Methoden wie all, reject und resolve. Sein Prototyp verfügt über Methoden wie then und catch. (ps: Was ist ein Prototyp: https://www.jb51.net/article/231967.htm) Das Promise-Objekt hat die folgenden zwei Eigenschaften.
Lass uns ein neues Versprechen erstellen let p = neues Versprechen(Funktion(auflösen, ablehnen){ //Führen Sie einige asynchrone Operationen aus setTimeout(function(){ console.log('Ausführung abgeschlossen, Promise'); resolve('Die zurückzugebenden Daten können beliebige Daten sein, z. B. Schnittstellen-Rückgabedaten'); }, 2000); }); Aktualisieren Sie die Seite und Sie werden feststellen, dass die Konsole direkt druckt Der Ausführungsprozess ist: Eine asynchrone Operation wird ausgeführt, d. h. setTimeout, und nach 2 Sekunden wird "Ausführung abgeschlossen" ausgegeben und die Resolve-Methode wird aufgerufen. Beachten! Ich habe gerade ein neues Objekt erstellt und es nicht aufgerufen. Die Funktion, die wir übergeben haben, wurde ausgeführt. Dies ist ein Detail, das Aufmerksamkeit erfordert. Wenn wir Promise verwenden, verpacken wir es normalerweise in eine Funktion und führen die Funktion bei Bedarf aus, zum Beispiel: <div onClick={promiseClick}>Asynchrone Anfrage starten</div> const promiseClick = () => { console.log('Click-Methode wird aufgerufen') let p = neues Versprechen(Funktion(auflösen, ablehnen){ //Führen Sie einige asynchrone Operationen aus setTimeout(function(){ console.log('Ausführung abgeschlossen, Promise'); resolve('Die zurückzugebenden Daten können beliebige Daten sein, z. B. Schnittstellen-Rückgabedaten'); }, 2000); }); Rückkehr p } Beim Aktualisieren der Seite erfolgt keine Reaktion, aber die Konsole druckt nach dem Klicken Wenn es in einer Funktion platziert wird, wird es nur ausgeführt, wenn es aufgerufen wird. Lösen wir also zwei Probleme:
Am Ende unserer gepackten Funktion geben wir ein Promise-Objekt zurück, d. h. wir erhalten ein Promise-Objekt, indem wir diese Funktion ausführen. Als Nächstes können Sie die Methoden then und catch auf das Promise-Objekt anwenden. Das ist die Stärke von Promise. Sehen Sie sich den folgenden Code an: promiseClick().then(Funktion(Daten){ konsole.log(Daten); //Sie können die übergebenen Daten später für andere Vorgänge verwenden//...... }); Diese Konsolenausgabe Zuerst wird die Methode aufgerufen, um das Versprechen auszuführen, und schließlich wird die then-Methode des Versprechens ausgeführt. Die then-Methode ist eine Funktion, die einen Parameter akzeptiert, der die von resolve zurückgegebenen Daten akzeptiert. Dies gibt aus: „Die zurückzugebenden Daten können beliebige Daten sein, z. B. Schnittstellenrückgabedaten.“ An diesem Punkt sollten Sie erkannt haben, dass die Funktion in then dieselbe ist wie unsere übliche Rückruffunktion, die ausgeführt werden kann, nachdem die asynchrone Aufgabe von promiseClick abgeschlossen ist. Dies ist die Funktion von Promise. Einfach ausgedrückt kann es die ursprüngliche Methode zum Schreiben von Rückrufen trennen und die Rückruffunktion nach der Ausführung des asynchronen Vorgangs in einer Kettenaufrufweise ausführen. Sie denken vielleicht, dass dies keinen Unterschied zum Schreiben einer Rückruffunktion darstellt. Was aber, wenn mehrere Ebenen von Rückrufen vorhanden sind? Was ist, wenn der Rückruf ebenfalls eine asynchrone Operation ist und nach der Ausführung eine entsprechende Rückruffunktion erforderlich ist? Sie können keinen weiteren Rückruf2 definieren und ihn an den Rückruf übergeben. Der Vorteil von Promise besteht darin, dass Sie weiterhin Promise-Objekte in die then-Methode schreiben und zurückgeben und anschließend weiterhin then aufrufen können, um Rückrufvorgänge auszuführen. Also: Das Wesentliche ist: Promise kann nur das Schreiben von Callback-Ebenen vereinfachen, aber tatsächlich ist das Wesentliche von Promise „state“, das die Methode zum Aufrechterhalten und Übergeben des Status verwendet, um den rechtzeitigen Aufruf der Callback-Funktion zu ermöglichen. Es ist viel einfacher und flexibler als das Übergeben der Callback-Funktion. Das richtige Szenario für die Verwendung von Promise ist also folgendes: VersprechenKlick() .dann(Funktion(Daten){ konsole.log(Daten); returniere runAsync2(); }) .dann(Funktion(Daten){ konsole.log(Daten); returniere runAsync3(); }) .dann(Funktion(Daten){ konsole.log(Daten); }); Auf diese Weise kann der Inhalt jedes asynchronen Rückrufs alle zwei Sekunden nacheinander ausgegeben werden und die zur Auflösung in runAsync2 übergebenen Daten können in der nächsten then-Methode abgerufen werden. (P.S.: Der Grund, warum es hier mehrfach ausgeführt wird, ist, dass ich diese Verwendung in einer React-Demo durchgeführt habe, als ich sie untersucht habe. Die Änderungen an mehreren Elementen auf der Seite führten dazu, dass die Seite mehrfach gerendert wurde. Wenn eine normale Seite nur einmal gerendert wird, wird sie auch nur einmal ausgeführt.) Verwendung von „reject“Oben ist eine Erklärung der Verwendung von „resolve“ von Promise. „resolve“ entspricht dem Rückruf, wenn Promise erfolgreich ist. Es ändert den Status von Promise in „fullfiled, then reject“ ist der Rückruf, wenn es fehlschlägt. Es ändert den Status des Versprechens in „abgelehnt“, sodass wir es dann erfassen und den Rückruf der „Fehler“-Situation ausführen können. Funktion promiseClick(){ let p = neues Versprechen(Funktion(auflösen, ablehnen){ setzeTimeout(Funktion(){ var num = Math.ceil(Math.random()*20); //Eine Zufallszahl zwischen 1 und 10 generieren console.log('Der Wert der generierten Zufallszahl:', num) wenn(Zahl<=10){ Lösung(Nummer); } anders{ reject('Die Zahl ist zu groß, um 10 zu sein, und der Rückruf schlägt fehl'); } }, 2000); }) Rückkehr p } versprechenClick().dann( Funktion(Daten){ console.log('erfolgreicher Rückruf aufgelöst'); console.log('Der vom erfolgreichen Rückruf akzeptierte Wert:',data); }, Funktion(Grund){ console.log('fehlgeschlagener Rückruf abgelehnt'); console.log('Fehlgeschlagener Ausführungsrückruf gibt Fehlergrund aus:',Grund); } ); Ausführungsergebnis: (PS: Dies wird auch mehrmals ausgeführt, sodass die Ausgabe mehrfach erfolgt. Der Grund für die mehrfache Ausführung ist derselbe wie beim letzten Mal.) Der obige Code: ruft die Methode promiseClick zur Ausführung auf und erhält nach 2 Sekunden eine Zufallszahl. Wenn sie kleiner als 10 ist, betrachten wir es als Erfolg und rufen resolve auf, um den Status von Promise auf erfüllt zu ändern. Andernfalls betrachten wir es als „Fehler“, rufen „reject“ auf und übergeben einen Parameter als Grund für den Fehler. Und ändern Sie den Status auf „Abgelehnt“ Führen Sie promiseClick aus und übergeben Sie in then zwei Parameter. Diese beiden Parameter sind zwei Funktionen. Die then-Methode kann zwei Parameter akzeptieren, der erste entspricht dem Resolve-Callback und der zweite dem Reject-Callback. (Das heißt, die then-Methode akzeptiert zwei Rückrufe, einen für Erfolg und einen für Misserfolg, und kann die Erfolgsdaten und den Grund für den Misserfolg in der Rückruffunktion abrufen.) So können wir die jeweils von Erfolg und Misserfolg übergebenen Daten abrufen und haben die oben genannten Laufergebnisse. Verwendung von „catch“Eine Methode, die parallel zur then-Methode des Promise-Objekts läuft, ist catch. Ähnlich wie try catch wird catch zum Abfangen von Ausnahmen verwendet, was dem Rückruf des abgelehnten zweiten Parameters entspricht, der von der then-Methode akzeptiert wurde, und zwar wie folgt: Funktion promiseClick(){ let p = neues Versprechen(Funktion(auflösen, ablehnen){ setzeTimeout(Funktion(){ var num = Math.ceil(Math.random()*20); //Eine Zufallszahl zwischen 1 und 10 generieren console.log('Der Wert der generierten Zufallszahl:', num) wenn(Zahl<=10){ Lösung(Nummer); } anders{ reject('Die Zahl ist zu groß, um 10 zu sein, und der Rückruf schlägt fehl'); } }, 2000); }) Rückkehr p } versprechenClick().dann( Funktion(Daten){ console.log('erfolgreicher Rückruf aufgelöst'); console.log('Der vom erfolgreichen Rückruf akzeptierte Wert:',data); } ) .catch(Funktion(Grund, Daten){ console.log('Abfangen des abgelehnten Fehler-Callbacks'); console.log('Catch konnte Rückruf nicht ausführen. Grund für Fehler:', Grund); }); Ausführungsergebnis: Der Effekt ist derselbe, als wenn Sie es in den zweiten Parameter von then schreiben. Es gibt den Grund für den fehlgeschlagenen Rückruf aus, wenn der Wert größer als 10 ist. Es hat jedoch auch eine andere Funktion: Wenn beim Ausführen des Resolve-Rückrufs (also des ersten Parameters im obigen then) eine Ausnahme (Codefehler) ausgelöst wird, wird kein Fehler gemeldet und JS eingefroren, sondern es wird in diese Catch-Methode gewechselt. wie folgt: Funktion promiseClick(){ let p = neues Versprechen(Funktion(auflösen, ablehnen){ setzeTimeout(Funktion(){ var num = Math.ceil(Math.random()*20); //Eine Zufallszahl zwischen 1 und 10 generieren console.log('Der Wert der generierten Zufallszahl:', num) wenn(Zahl<=10){ Lösung (Nummer); } anders{ reject('Die Zahl ist zu groß, um 10 zu sein, und der Rückruf schlägt fehl'); } }, 2000); }) Rückkehr p } versprechenClick().dann( Funktion(Daten){ console.log('erfolgreicher Rückruf aufgelöst'); console.log('Der vom erfolgreichen Rückruf akzeptierte Wert:',data); Konsole.log(keine Daten); } ) .catch(Funktion(Grund, Daten){ console.log('Abfangen des abgelehnten Fehler-Callbacks'); console.log('Catch konnte Rückruf nicht ausführen. Grund für Fehler:', Grund); }); Ausführungsergebnis: Im Resolve-Callback führen wir console.log(noData) aus, aber die Variable noData ist nicht definiert. Wenn wir Promise nicht verwenden, meldet der Code einen Fehler in der Konsole, wenn er bis zu diesem Punkt läuft, und wird nicht weiter ausgeführt. Aber hier erhalten wir das in der obigen Abbildung gezeigte Ergebnis. Dies bedeutet, dass wir die Catch-Methode aufrufen und die Fehlerursache an den Reason-Parameter übergeben. Auch wenn ein Fehler im Code vorliegt, wird kein Fehler gemeldet. Nutzung allerEine andere Methode auf derselben Ebene wie then, die All-Methode, bietet die Möglichkeit, asynchrone Vorgänge parallel auszuführen, und führt den Rückruf nur aus, wenn alle asynchronen Vorgänge ausgeführt wurden und die Ausführungsergebnisse erfolgreich sind. Kopieren Sie die obige Methode zweimal und benennen Sie sie wie folgt um: promiseClick3(), promiseClick2(), promiseClick1() Funktion promiseClick1(){ let p = neues Versprechen(Funktion(auflösen, ablehnen){ setzeTimeout(Funktion(){ var num = Math.ceil(Math.random()*20); //Eine Zufallszahl zwischen 1 und 10 generieren console.log('Der Wert der generierten Zufallszahl:', num) wenn(Zahl<=10){ Lösung(Nummer); } anders{ reject('Die Zahl ist zu groß, um 10 zu sein, und der Rückruf schlägt fehl'); } }, 2000); }) Rückkehr p } Funktion promiseClick2(){ let p = neues Versprechen(Funktion(auflösen, ablehnen){ setzeTimeout(Funktion(){ var num = Math.ceil(Math.random()*20); //Eine Zufallszahl zwischen 1 und 10 generieren console.log('Der Wert der generierten Zufallszahl:', num) wenn(Zahl<=10){ Lösung(Nummer); } anders{ reject('Die Zahl ist zu groß, um 10 zu sein, und der Rückruf schlägt fehl'); } }, 2000); }) Rückkehr p } Funktion promiseClick3(){ let p = neues Versprechen(Funktion(auflösen, ablehnen){ setzeTimeout(Funktion(){ var num = Math.ceil(Math.random()*20); //Eine Zufallszahl zwischen 1 und 10 generieren console.log('Der Wert der generierten Zufallszahl:', num) wenn(Zahl<=10){ Lösung(Nummer); } anders{ reject('Die Zahl ist zu groß, um 10 zu sein, und der Rückruf schlägt fehl'); } }, 2000); }) Rückkehr p } Versprechen .alle([versprechenKlick3(), versprechenKlick2(), versprechenKlick1()]) .dann(Funktion(Ergebnisse){ console.log(Ergebnisse); }); Zur Ausführung wird Promise.all verwendet. all empfängt einen Array-Parameter. Dieser Parametersatz umfasst alle Methoden, die asynchrone Operationen ausführen müssen. Die darin enthaltenen Werte werden schließlich als das Promise-Objekt zurückgegeben. Auf diese Weise werden die drei asynchronen Vorgänge parallel ausgeführt, und der nächste Vorgang wird erst ausgeführt, wenn sie alle ausgeführt wurden. Wo also sind die von den drei asynchronen Operationen zurückgegebenen Daten geblieben? Alle sind in then. Alle werden die Ergebnisse aller asynchronen Operationen in ein Array einfügen und an then übergeben. Dann wird der erfolgreiche Rückruf der then-Methode ausgeführt, um die Ergebnisse zu erhalten. Die Ergebnisse sind wie folgt: (Die Ergebnisse werden durch separate Ausführung erhalten. Alle werden die drei Funktionen einheitlich ausführen und die Werte in einem Array speichern und sie für die Rückrufausgabe an then zurückgeben): Auf diese Weise können Sie mit all mehrere asynchrone Vorgänge parallel ausführen und alle zurückgegebenen Daten in einem Rückruf verarbeiten. Wenn Sie beispielsweise alle Daten im Voraus vorbereiten müssen, bevor Sie die Seite rendern, können Sie mit all mehrere asynchrone Vorgänge ausführen, um alle Daten vor dem Rendern zu verarbeiten. Verwendung von Rasse„all“ bedeutet, dass gewartet wird, bis alle asynchronen Vorgänge abgeschlossen sind, bevor die Methode „then“ ausgeführt wird, während die Methode „race“ das Gegenteil bewirkt. Der Rückruf wird zuerst ausgeführt, wenn der Vorgang zuerst abgeschlossen ist. Der erste, der ausgeführt wird, unabhängig davon, ob es sich um einen erfolgreichen Rückruf oder einen fehlgeschlagenen Rückruf des Rennens handelt, führt keinen Rückruf des Rennens erneut aus Wir ändern die Verzögerung der obigen Methode auf 234 Sekunden bzw. Funktion promiseClick1(){ let p = neues Versprechen(Funktion(auflösen, ablehnen){ setzeTimeout(Funktion(){ var num = Math.ceil(Math.random()*20); //Generiere eine Zufallszahl von 1 bis 10 console.log('2s Zufallszahl generierter Wert:',num) wenn(Zahl<=10){ Lösung (Nummer); } anders{ reject('Die 2s-Zahl ist zu groß, um 10 zu sein, und der Rückruf schlägt fehl'); } }, 2000); }) Rückkehr p } Funktion promiseClick2(){ let p = neues Versprechen(Funktion(auflösen, ablehnen){ setzeTimeout(Funktion(){ var num = Math.ceil(Math.random()*20); //Eine Zufallszahl von 1 bis 10 generieren console.log('3s Zufallszahl generierter Wert:',num) wenn(Zahl<=10){ Lösung(Nummer); } anders{ reject('Die 3s-Zahl ist zu groß, um 10 zu sein, und der Rückruf schlägt fehl'); } }, 3000); }) Rückkehr p } Funktion promiseClick3(){ let p = neues Versprechen(Funktion(auflösen, ablehnen){ setzeTimeout(Funktion(){ var num = Math.ceil(Math.random()*20); //Eine Zufallszahl von 1 bis 10 generieren console.log('4s Zufallszahl generierter Wert:',num) wenn(Zahl<=10){ Lösung(Nummer); } anders{ reject('4s-Zahl ist zu groß, um 10 zu sein, und der Rückruf schlägt fehl'); } }, 4000); }) Rückkehr p } Versprechen .race([VersprechenKlick3(), VersprechenKlick2(), VersprechenKlick1()]) .dann(Funktion(Ergebnisse){ console.log('Erfolg',Ergebnisse); },Funktion(Grund){ console.log('fehlgeschlagen',Grund); }); Wenn promiseClick1 nach 2 Sekunden ausgeführt wird, ist es in den Rückruf eingetreten. Wenn der Rückruf in dann ausgeführt wird, sind promiseClick2() und promiseClick3() noch nicht beendet und werden immer noch ausgeführt. Dann werden nach weiteren 3 Sekunden die entsprechenden Werte ausgegeben, es erfolgt jedoch kein erneuter Rückruf des Rennens. Wie in der Abbildung gezeigt, werden die verbleibenden Funktionen nach 2 Sekunden, bei denen 10 generiert wird, weiter ausgeführt, treten aber nicht erneut in einen Race-Callback ein. 2 Sekunden generieren 16 und treten in den fehlgeschlagenen Race-Callback ein, und der Rest wird weiter ausgeführt, tritt aber nicht erneut in einen Race-Callback ein. Beispielsweise kann „race“ verwendet werden, um die Methode then auszuführen, wenn eine Anforderung innerhalb von 10 Sekunden erfolgreich ist. Wenn die Anforderung nicht innerhalb von 10 Sekunden erfolgreich ist, wird der Reject-Callback aufgerufen, um eine andere Operation auszuführen. Ergänzung: (Da mich jemand gefragt hat, wie man die Verwendung von Race implementiert, wird beispielsweise die Methode then verwendet, wenn eine Anforderung innerhalb von 10 Sekunden erfolgreich ist. Wenn die Anforderung nicht innerhalb von 10 Sekunden erfolgreich ist, wird der Reject-Callback aufgerufen, um eine andere Operation auszuführen. Bei dieser Frage glaube ich, dass mit meinem Ausdruck etwas nicht stimmt, also möchte ich ein Beispiel geben.) //Tabellendaten anfordern Funktion requestTableList(){ var p = neues Versprechen((lösen, ablehnen) => { //Gehe zum Backend, um Daten anzufordern. Dies kann Ajax, Axios oder Fetch sein. Entschlossenheit (res); }); Rückgabe p; } // Verzögerungsfunktion, die verwendet wird, um die Anforderung auf 10 Sekunden zu begrenzen Funktion Timeout () { var p = neues Versprechen((lösen, ablehnen) => { setzeTimeout(() => { ablehnen('Anforderungs-Timeout'); }, 10000); }); Rückgabe p; } Versprechen.race([requestTableList(), timeout()]).then((Daten) => { //Rückrufverarbeitung erfolgreich durchführen console.log(data); }).catch((err) => { // Fehler bei der Verarbeitung des Callbacks console.log(err); }); Fordern Sie Schnittstellendaten an, zeigen Sie die Daten an, wenn die Anforderung innerhalb von 10 Sekunden abgeschlossen ist, und melden Sie, dass die Anforderung fehlgeschlagen ist, wenn die Anforderung nicht innerhalb von 10 Sekunden abgeschlossen ist Hier werden zwei Versprechen definiert, eines zum Anfordern von Daten und das andere zum Zeitablauf von 10 Sekunden. Die beiden Versprechen werden in das Rennen ums Rennen geworfen. Wenn die Datenanforderung zuerst abgeschlossen ist, wird direkt der Rückruf „.then success“ aufgerufen, um die angeforderten Daten anzuzeigen. Wenn der Zeitablauf zuerst abgeschlossen ist, d. h. die Datenanforderung nach 10 Sekunden nicht erfolgreich war, wird zuerst der Rückruf „Race Failure“ aufgerufen, der den Benutzer darüber informiert, dass die Datenanforderung fehlgeschlagen ist, und der Rückruf „.catch“ aufgerufen. (ps: oder geben Sie den Rückruf „Reject Failure“ ein. Wenn in „.then“ kein Rückruf „Reject“ vorhanden ist, wird der Rückruf „Failure“ direkt in „.catch“ aufgerufen.) Damit ist dieser Artikel zur detaillierten Verwendung von ES6 Promise abgeschlossen. Ich hoffe, dass es für jedermanns Studium hilfreich sein wird, und ich hoffe auch, dass jeder 123WORDPRESS.COM unterstützen wird. Das könnte Sie auch interessieren:
|
<<: HTML-Zeichnungsbenutzer-Registrierungsseite
>>: Einfache Tipps zur Erhöhung der Ladegeschwindigkeit von Webseiten
Hintergrund CVE-2021-21972 Eine nicht authentifiz...
Flex-Grundkonzepte Flex-Layout (Flex ist die Abkü...
Der zuständige Verantwortliche für Baidu Input Met...
Kürzlich habe ich festgestellt, dass die Serverze...
XML/HTML-CodeInhalt in die Zwischenablage kopiere...
Boolescher MySQL-Wert, speichert „false“ oder „tr...
Inhaltsverzeichnis Lösungsanalyse Scheibe Lebensl...
Vorwort Wir alle wissen, dass man QR-Codes in off...
1. Datenbanktransaktionen verringern die Datenban...
In diesem Artikel wird hauptsächlich die Verwendun...
Sie können MySQL-SQL-Anweisungen Kommentare hinzu...
Inhaltsverzeichnis 1. Wie verwende ich Mixin? 2. ...
Inhaltsverzeichnis Überblick Durchführung Schutz-...
<br />Originaltext: http://andymao.com/andy/...
Das JD-Karussell wurde mit reinem HTML und CSS im...