Bei der Verwendung der Versprechensketten von JavaScript besteht eine häufige Gefahr darin, setTimeout falsch zu verwenden. Im folgenden Beispiel gibt die getLinks-Funktion ein Versprechen zurück, das eine Reihe von Links von einer bereitgestellten URL abruft:
<code class="javascript">function getLinks(url) { return new Promise((resolve, reject) => { // ...XHR logic to fetch links... }); }</code>
Anschließend ruft ein weiterer getLinks-Aufruf den Inhalt des ersten Links ab:
<code class="javascript">getLinks('links.txt') .then((links) => { const allLinks = JSON.parse(links); return getLinks(allLinks["one"] + ".txt"); }) .then((topic) => { // ...logic to write topic to body... setTimeout(() => { return getLinks(allLinks["two"] + ".txt"); // This is where the error occurs }, 1000); });</code>
Dieser Code verursacht jedoch einen JSON-Parsing-Fehler (JSON.parse: unerwartetes Zeichen...). Der Grund liegt in der unsachgemäßen Verwendung von setTimeout:
Eine Versprechenskette ist eine Reihe asynchroner Operationen, die nacheinander ausgeführt werden. Jede Operation (oder jeder Handler) gibt ein Versprechen zurück. Folglich wird jedem then-Handler das Ergebnis des vorherigen Versprechens übergeben.
Der setTimeout-Rückruf wird asynchron ausgeführt, nicht als Teil der Versprechenskette. Die Rückgabe eines Werts vom setTimeout-Rückruf gibt keinen Wert vom then-Handler zurück. Stattdessen muss der Wert zurückgegeben werden, bevor der Then-Handler abgeschlossen ist.
Um die Ausführung nachfolgender Versprechen in einer Versprechenskette zu verzögern, muss man ein Versprechen vom Then-Handler zurückgeben wird nach der gewünschten Verzögerung aufgelöst:
<code class="javascript">... .then((topic) => { writeToBody(topic); // Replace the setTimeout call with a delay promise return delay(1000).then(() => { return getLinks(allLinks["two"] + ".txt"); }); });</code>
Die Verzögerungsfunktion kann wie folgt implementiert werden:
<code class="javascript">function delay(t, val) { return new Promise((resolve) => setTimeout(resolve, t, val)); }</code>
Alternativ kann man eine Erweiterungsmethode auf Promise definieren, um die Syntax zu vereinfachen:
<code class="javascript">Promise.prototype.delay = function(t) { return this.then((val) => { return delay(t, val); }); } ... .then((topic) => { writeToBody(topic); return delay(1000).delay(500); });</code>
Dieser Ansatz stellt sicher, dass die Versprechenskette intakt bleibt und dass die nachfolgenden Vorgänge wie erwartet ausgeführt werden.
Das obige ist der detaillierte Inhalt vonWarum verursacht „setTimeout' einen JSON-Parse-Fehler in Promise Chains?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!