Home  >  Article  >  Web Front-end  >  Why Does `setTimeout` Cause a JSON Parse Error in Promise Chains?

Why Does `setTimeout` Cause a JSON Parse Error in Promise Chains?

Susan Sarandon
Susan SarandonOriginal
2024-10-30 14:14:02204browse

Why Does `setTimeout` Cause a JSON Parse Error in Promise Chains?

Why Does setTimeout Cause a JSON Parse Error in Promise Chains?

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:

Understanding the Promise Chain

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 Role of setTimeout

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.

The Solution

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn