Fetch超时设置与终止请求详解


Posted in Javascript onMay 18, 2019

1.基本使用

Fetch 是一个新的端获取资源的接口,用于替换笨重繁琐XMLHttpRequest.它有了Request 和 Response 以及Headers对象的概念,与后端语言请求资源更接近。

一个简单的GET请求

fetch('https://www.baidu.com')
  .then(resp=>resp.text()) // 转换成文本对象
  .then(resp=>console.log(resp)) // 输出请求内容
  .catch(error => console.error(error));

一个简单的POST请求

fetch('https://www.easy-mock.com/mock/5ca59ba44ba86c23d507bd40/example/getUser',{method:"post"})
  .then(resp=>resp.json()) //转换成Json对象
  .then(resp=>console.log(resp)) //输出Json内容
  .catch(error => console.error(error));

更多Fetch相关详细,可查看MDN文档 developer.mozilla.org/en-US/docs/…

2.超时设置

在使用XMLHttpRequest可以设置请求超时时间,可是转用Fetch后,超时时间设置不见了,在网络不可靠的情况下,超时设置往往很有用

ES6以后Promise 出现解决地狱回调等不优雅的代码风格。个人理解这个更像是一个生产者和消费者的关系,查看 Promise文档,有以下两个方法

  1. Promise.race([promise1,promise2]) 传入多个Promise对象,等待最快对象完成
  2. Promise.all([promise1,promise2]) 传入多个Promise 对象,等待所有对象完成

有了以上知识后,结合函数setTimeout就可以实现超时设置

//ahutor:herbert qq:464884492
let timeoutPromise = (timeout) => {
 return new Promise((resolve, reject) => {
  setTimeout(() => {
   resolve("我是 timeoutPromise,已经完成了");
  }, timeout);
 });
}
let requestPromise = (url) => {
 return fetch(url);
};
Promise.race([timeoutPromise(1000), requestPromise("https://www.baidu.com")])
 .then(resp => {
  console.log(resp);
 })
 .catch(error => {
  console.log(error);
 });

3.取消请求

将上边的代码拷贝的浏览器控制台并将network设置为Slow3G。运行就会发现,虽然我们在控制台看到了超时信息,但切换到netwok页签中发现请求依然正常进行中,并返回了正确的内容。这并不是我想要的结果,我希望超时时间到了,请求也应该终止。

fetch请求成功后,默认返回一个Response对象,那么我们如何在代码中构造一个这样的对象呢?

timeoutResp=new Response("timeout", { status: 504, statusText: "timeout " })
 successResp=new Response("ok", { status: 200, statusText: "ok " })

AbortController 用于手动终止一个或多个DOM请求,通过该对象的AbortSignal注入的Fetch的请求中。所以需要完美实现timeout功能加上这个就对了

//ahutor:herbert qq:464884492
let controller = new AbortController();
let signal = controller.signal;

let timeoutPromise = (timeout) => {
 return new Promise((resolve, reject) => {
  setTimeout(() => {
   resolve(new Response("timeout", { status: 504, statusText: "timeout " }));
   controller.abort();
  }, timeout);
 });
}
let requestPromise = (url) => {
 return fetch(url, {
  signal: signal
 });
};
Promise.race([timeoutPromise(1000), requestPromise("https://www.baidu.com")])
 .then(resp => {
  console.log(resp);
 })
 .catch(error => {
  console.log(error);
 });

4.总结

第一次在项目中使用fetch,在面向API编程的过程中,发现fetch没有超时的设置。第一时间查看了MDN文档以及向搜索引擎找寻实现功能的灵感(copy+c)。有些朋友在settimeout中通过 reject(new Error('网络超时'))实现。其实这样只是让前端感知当前请求超时了,并没有真正终止本次请求。所以必须借助AbortSignal信号对象。此功能目前还处于试验阶段,使用需谨慎。

demo地址 https://github.com/464884492/blog/blob/master/demo/fetch/fetchdemo.js

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
根据对象的某一属性进行排序的js代码(如:name,age)
Aug 10 Javascript
js 连接数据库如何操作数据库中的数据
Nov 23 Javascript
5款JavaScript代码压缩工具推荐
Jul 07 Javascript
java、javascript实现附件下载示例
Aug 14 Javascript
js倒计时显示实例
Dec 11 Javascript
AngularJS基于ui-route实现深层路由的方法【路由嵌套】
Dec 14 Javascript
BackBone及其实例探究_动力节点Java学院整理
Jul 14 Javascript
详解vue-cli脚手架build目录中的dev-server.js配置文件
Nov 24 Javascript
JavaScript数据结构之双向链表和双向循环链表的实现
Nov 28 Javascript
详解ES6 Promise对象then方法链式调用
Oct 20 Javascript
JavaScript数据结构之栈实例用法
Jan 18 Javascript
适用于 Vue 的播放器组件Vue-Video-Player操作
Nov 16 Javascript
微信小程序实现搜索历史功能
Mar 26 #Javascript
微信小程序云开发修改云数据库中的数据方法
May 18 #Javascript
小程序云开发教程如何使用云函数实现点赞功能
May 18 #Javascript
微信小程序实现元素渐入渐出动画效果封装方法
May 18 #Javascript
微信小程序收货地址API兼容低版本解决方法
May 18 #Javascript
小程序云开发获取不到数据库记录的解决方法
May 18 #Javascript
小程序云开发之用户注册登录
May 18 #Javascript
You might like
JQuery入门——用one()方法绑定事件处理函数(仅触发一次)
2013/02/05 Javascript
php和js对数据库图片进行等比缩放示例
2014/04/28 Javascript
基于jQuery实现文本框缩放以及上下移动功能
2014/11/24 Javascript
文件上传的几个示例分享【推荐】
2016/12/16 Javascript
DWR3 访问WEB元素的两种方法实例详解
2017/01/03 Javascript
Vue计算属性的使用
2017/08/04 Javascript
详解webpack2+React 实例demo
2017/09/11 Javascript
Angularjs 1.3 中的$parse实例代码
2017/09/14 Javascript
Angular 4.x+Ionic3踩坑之Ionic3.x pop反向传值详解
2018/03/13 Javascript
Vue项目中如何引入icon图标
2018/03/28 Javascript
使用JS代码实现俄罗斯方块游戏
2018/08/03 Javascript
JS实现的杨辉三角【帕斯卡三角形】算法示例
2019/02/26 Javascript
原生js实现获取form表单数据代码实例
2019/03/27 Javascript
vue-cli3项目展示本地Markdown文件的方法
2019/06/07 Javascript
express框架中使用jwt实现验证的方法
2019/08/25 Javascript
vue实现图片上传功能
2020/05/28 Javascript
解决antd datepicker 获取时间默认少8个小时的问题
2020/10/29 Javascript
[07:55]2014DOTA2 TI正赛第三日 VG上演推进荣耀DKEG告别
2014/07/21 DOTA
[34:44]Liquid vs TNC Supermajor 胜者组 BO3 第二场 6.4
2018/06/05 DOTA
Python中的random()方法的使用介绍
2015/05/15 Python
使用NumPy和pandas对CSV文件进行写操作的实例
2018/06/14 Python
Python 实现异步调用函数的示例讲解
2018/10/14 Python
python中dir()与__dict__属性的区别浅析
2018/12/10 Python
Python列表list排列组合操作示例
2018/12/18 Python
利用OpenCV和Python实现查找图片差异
2019/12/19 Python
python框架flask入门之路由及简单实现方法
2020/06/07 Python
Python如何将模块打包并发布
2020/08/30 Python
python time()的实例用法
2020/11/03 Python
html5中valid、invalid、required的定义
2014/02/21 HTML / CSS
绘画专业自荐信范文
2014/02/23 职场文书
合伙经营协议书范本(通用版)
2014/12/03 职场文书
导游词怎么写
2015/02/04 职场文书
导游词之南迦巴瓦峰
2019/11/19 职场文书
MySQL开启事务的方式
2021/06/26 MySQL
MySQL时区造成时差问题
2022/04/13 MySQL
带你了解Java中的ForkJoin
2022/04/28 Java/Android