返回

让fetch也可以timeout

前端

众所周知,原生的HTML5 API fetch并不支持timeout属性,习惯了jQuery的ajax配置的同学,如果一时在fetch找不到配置timeout的地方,也许会很纠结。

其实,只要简单几步,就可以让fetch也拥有timeout的能力。

首先,我们需要创建一个新的 Promise 对象,并将 fetch 的结果作为它的 resolve 值。

const fetchWithTimeout = (url, options, timeout = 5000) => {
  return new Promise((resolve, reject) => {
    const controller = new AbortController();
    const signal = controller.signal;
    const timeoutId = setTimeout(() => {
      controller.abort();
    }, timeout);
    fetch(url, { ...options, signal })
      .then(res => {
        clearTimeout(timeoutId);
        resolve(res);
      })
      .catch(err => {
        clearTimeout(timeoutId);
        reject(err);
      });
  });
};

然后,我们就可以像使用普通的fetch一样使用fetchWithTimeout了。

fetchWithTimeout('https://example.com')
  .then(res => {
    console.log('请求成功', res);
  })
  .catch(err => {
    console.log('请求失败', err);
  });

当请求超时时,fetchWithTimeout 会抛出一个 AbortError 异常,我们可以在 .catch() 中捕获这个异常,并做出相应的处理。

fetchWithTimeout('https://example.com', { timeout: 1000 })
  .then(res => {
    console.log('请求成功', res);
  })
  .catch(err => {
    if (err.name === 'AbortError') {
      console.log('请求超时');
    } else {
      console.log('请求失败', err);
    }
  });

以上就是让fetch也拥有timeout能力的解决方案,希望能对大家有所帮助。