fetch with a timeout

stereobooster - Oct 8 '18 - - Dev Community

You may know (or will learn it right now) that new Web API fetch comes without a timeout. I guess this is because it is built more around the idea of streams.
If you, like me, want to use fetch for AJAX(XMLHttpRequest) you would expect it to support timeout. I googled it and indeed people have the same issue. What I noticed is that most solution built around setTimeout and Promise.reject, most solutions don't bother to cancel the actual request.

So I created this snippet, which will not just timeout, but also cancel the network request:

const timeoutableFetch = (url, options = {}) => {
  let { timeout = 5000, ...rest } = options;
  if (rest.signal) throw new Error("Signal not supported in timeoutable fetch");
  const controller = new AbortController();
  const { signal } = controller;
  return new Promise((resolve, reject) => {
    const timer = setTimeout(() => {
      reject(new Error("Timeout for Promise"));
      controller.abort();
    }, timeout);
    fetch(url, { signal, ...rest })
      .finally(() => clearTimeout(timer))
      .then(resolve, reject);
  });
};

requires AbortController. WDYT?

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .