如何给fetch添加超时功能

发布时间 2023-06-13 16:06:51作者: 10后程序员劝退师

目前大部分的实现方式是利用 promise.race

const fetchTimeOut = (timeout = 1000) => {
    return new Promise((resolve, reject) => {
        setTimeOut(() => {
           reject('fetch timeOut')
        },timeout)
    })
}
const request = (url, options) => {
    
   const fetchApi = fetch(url, options).then(resolve, reject)
   
   return new Promise.race([ fetchApi, fetchTimeOut(2000) ]).then((res) => {
             //接口请求成功
          }).catch((cat) => {
             //接口超时
             console.log(cat)
          })
   
}
function request(url, option){
   const timeOut = option.timeOut || 5000
}
// 但是每次调用request都需要传递时间,如果不传将会固定死项目中的超时时间,丧失了通用性

 

以下介绍一种方式 更好的来实现

function createFetchWithTimeout(timeOut = 1000){
   return function(url, options){
       return new Promise((resolve, reject) => {
          const singalController = new AbortController()
          fetch(url, {
             ...options,
             signal: singController.signal
          }).then(resolve, reject)
          setTimeout(() => {
               reject(new Error('fetch timout'))  //如果fetch的resolve成功了,这里的reject将不会生效,因为promise的状态只会修改第一次
               //取消请求
               singalController.abort()
          },timeOut)
       })
   }
}

const request = createFetchWithTimeout(2000)
request('/xxxx/xxx', data)

const request2 = createFetchWithTimeout(3000)
request('/xxxx/xxx2', data2)