Fetch设置超时请求

promise + fetch + AbortController + setTimeOut

这是一段正常的fetch请求

js 复制代码
fetch('www.baidu.com',{})
  .then(res=>res.json())
  .then(console.log(res) // 打印返回结果
  .catch(...) // 捕获错误信息

这段代码实现: 返回成功打印, 返回失败捕获, 无限制超时时间.

假设限制超时间为3000ms, 需要怎么写呢?

尝试一下使用setTimeOut

在n个时间后执行

js 复制代码
let timeoutPromise = (timeout) => {  // 模拟返回一个promise(超时版本)
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(new Response("timeout", { status: 504, statusText: "timeout " }));
        }, timeout);
    });
}

这段代码的执行, 我们可以收到一个n时间后的超时返回.

什么是AbortController

AbortController 接口表示一个控制器对象,允许你根据需要中止一个或多个 Web 请求。

js 复制代码
// 构建一个AbortController
const AC = new AbortController();
const signal = AC.signal; // signal注入请求(例如fetch, 可以终止请求抛出error)

fetch('www.baidu.com',{signal: signal})
  .then(res=>res.json())
  .then(res=>{
    console.log(res);
  })
  .catch(err=>{
    console.log("出错了!", err);
  })
// 例如用一个按钮来终止, 把网络速度调整为slow 3G
abortBtn.addEventListener("click", () => {
  if (controller) {
    AC.abort();
    console.log("中止下载");
  }
});
// 也可以用setTimeOut
setTimeOut(()=>{
  AC.abort();
  alert('终止请求');
}, 100)

实现请求的超时设置

两个请求相互竞争, 谁先完成谁先返回, 真的请求和假(模拟)的请求, 模拟一个八秒就立刻返回的请求, 真的请求如果不能在八秒内请求成功, 那么假的就会立刻返回. 可以想到使用Promise.race方法. 请求成功立刻终止另一个请求AbortController.

js 复制代码
// 公用的AbortController
const AC = new AbortController();
const signal = AC.signal;

// 我们要在100ms内请求百度网址成功
function getBaidu() {
  // 浅浅将signal注入其中
  return fetch('https://www.baidu.com', {signal});
}

// 做一个定时resolve的promise用于和真请求竞争
const timeOutPromise = new Promise((resolve, reject)=>{
  setTimeout(()=>{
    resolve({ status: 504, statusText: "timeout " });
    AC.abort(); // 百度不给我们响应, 我们就终止请求
  }, 100)  // 100ms内百度不resolve我们先resolve
})

// 开始请求(竞争)
Promise.race([timeOutPromise, getBaidu()])
  .then(res=>{
    console.log(res)
  })
  .cathch(err=>{
    console.log(err)
  })
相关推荐
来自星星的坤1 小时前
【Vue 3 + Vue Router 4】如何正确重置路由实例(resetRouter)——避免“VueRouter is not defined”错误
前端·javascript·vue.js
香蕉可乐荷包蛋5 小时前
浅入ES5、ES6(ES2015)、ES2023(ES14)版本对比,及使用建议---ES6就够用(个人觉得)
前端·javascript·es6
未来之窗软件服务6 小时前
资源管理器必要性———仙盟创梦IDE
前端·javascript·ide·仙盟创梦ide
西哥写代码7 小时前
基于cornerstone3D的dicom影像浏览器 第十八章 自定义序列自动播放条
前端·javascript·vue
清风细雨_林木木7 小时前
Vue 中生成源码映射文件,配置 map
前端·javascript·vue.js
雪芽蓝域zzs8 小时前
JavaScript splice() 方法
开发语言·javascript·ecmascript
森叶9 小时前
Electron 主进程中使用Worker来创建不同间隔的定时器实现过程
前端·javascript·electron
霸王蟹9 小时前
React 19 中的useRef得到了进一步加强。
前端·javascript·笔记·学习·react.js·ts
霸王蟹9 小时前
React 19版本refs也支持清理函数了。
前端·javascript·笔记·react.js·前端框架·ts
codelxy9 小时前
vue引用cesium,解决“Not allowed to load local resource”报错
javascript·vue.js