fetch 设置超时断开请求

2,438 阅读1分钟

AbortController.abort()

中止一个尚未完成的Web(网络)请求。这能够中止fetch 请求,任何响应Body的消费者和流

Promise.race()

race 函数返回一个 Promise,它将与第一个传递的 promise 相同的完成方式被完成。它可以是完成( resolves),也可以是失败(rejects),这要取决于第一个完成的方式是两个中的哪个。 如果传的迭代是空的,则返回的 promise 将永远等待。 如果迭代包含一个或多个非承诺值和/或已解决/拒绝的承诺,则 Promise.race 将解析为迭代中找到的第一个值。 返回第一个完成的Promise


/**
 * 实现fetch的timeout 功能
 * @param {object} fecthPromise fecth
 * @param {Number} timeout 超时设置,默认5000ms
 * */
export function fetch_timeout(fecthPromise, timeout = 5000,controller) {
  let abort = null;
  let abortPromise = new Promise((resolve, reject) => {
    abort = () => {
      return reject({
        code: 504,
        message: '请求超时!',
      });
    };
  }); 
  // 最快出结果的promise 作为结果
  let resultPromise = Promise.race([fecthPromise, abortPromise]);
  setTimeout(() => {
    abort();
    controller.abort();
  }, timeout);

  return resultPromise.then((res) => {
    clearTimeout(timeout);
    return res;
  });
}

使用

    let controller = new AbortController();
    const signal = controller.signal;
    fetch_timeout(
      fetch(url, {
        mode: 'cors',
        credentials: 'include',
        ...options,
        signal
      }),5000,controller
    ) .then(function(response) {
        ...
    }).catch(function(e) {
        reports.textContent = 'Download error: ' + e.message;
    })