0

I have multiple api requests which one of them depends on first one's result and I am trying to add a timeout error if total request time of all requests is over a specific amount of time. So far I've only seen a solution to set a timeout to single api request and couldn't transform it to my solution.

fetch(
  `https://en.wikipedia.org/w/api.php?action=parse&format=json&origin=*&page=earth&prop=sections&disabletoc=1`
)
  .then((data) => {
    return data.json();
  })
  .then((data) => {
    const _index = data.parse.sections.find((one) =>
      one.line.toLowerCase().includes("internal")
    ).index;

    const urls = [
      `https://en.wikipedia.org/w/api.php?action=parse&format=json&origin=*&page=earth&prop=wikitext&section=${_index}&disabletoc=1`,
      `https://api.le-systeme-solaire.net/rest.php/bodies/earth`,
    ];

    const requests = urls.map((url) => fetch(url));

    return Promise.all(requests);
  })
  .then((res) => {
    return Promise.all(res.map((r) => r.json()));
  })
  .then((data) => {
    console.log(data); // final data
  })
  .catch((err) => console.log(err));

My attempt

const controller = new AbortController();

fetchTimeout(
  `https://en.wikipedia.org/w/api.php?action=parse&format=json&origin=*&page=${_planet}&prop=sections&disabletoc=1`,
  5000,
  { signal: controller.signal }
)
  .then((response) => response.json())
  .then((data) => {
    //     const _index = data.parse.sections.find((one) =>
    //       one.line.toLowerCase().includes("internal")
    //     ).index;
    // same codes from above
    
    // currently timeout error only works for first api request which is not what I want
  })
  .catch((error) => {
    if (error.name === "AbortError") {
      alert("please check your connection");
    } else {
        console.log(`error: ${error.name}`)
    }
  });

function fetchTimeout(url, ms, { signal, ...options } = {}) {
  const controller = new AbortController();
  const promise = fetch(url, { signal: controller.signal, ...options });
  if (signal) signal.addEventListener("abort", () => controller.abort());
  const timeout = setTimeout(() => controller.abort(), ms);
  return promise.finally(() => clearTimeout(timeout));
}
Kaung Khant Zaw
  • 1,163
  • 1
  • 9
  • 23

0 Answers0