When utilizing JavaScript's promise chains, a common pitfall is attempting to use setTimeout incorrectly. In the example below, the getLinks function returns a promise that fetches a set of links from a provided URL:
<code class="javascript">function getLinks(url) { return new Promise((resolve, reject) => { // ...XHR logic to fetch links... }); }</code>
Subsequently, another getLinks call retrieves the content of the first link:
<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>
However, this code causes a JSON parsing error (JSON.parse: unexpected character...). The reason lies in the improper use of setTimeout:
A promise chain is a series of asynchronous operations that execute sequentially. Each operation (or then handler) returns a promise. Consequently, each then handler is passed the result of the previous promise.
The setTimeout callback is executed asynchronously, not as part of the promise chain. Returning a value from the setTimeout callback will not return a value from the then handler. Instead, the value must be returned before the then handler completes.
To delay the execution of subsequent promises in a promise chain, one needs to return a promise from the then handler that resolves after the desired delay:
<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>
The delay function can be implemented as follows:
<code class="javascript">function delay(t, val) { return new Promise((resolve) => setTimeout(resolve, t, val)); }</code>
Alternatively, one can define an extension method on Promise to simplify the syntax:
<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>
This approach ensures that the promise chain remains intact and that the subsequent operations execute as expected.
The above is the detailed content of Why Does `setTimeout` Cause a JSON Parse Error in Promise Chains?. For more information, please follow other related articles on the PHP Chinese website!