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 相关文章推荐
jQuery Validation插件remote验证方式的Bug解决
Jul 01 Javascript
jquery选择器(常用选择器说明)
Sep 28 Javascript
ASP.NET jQuery 实例5 (显示CheckBoxList成员选中的内容)
Jan 13 Javascript
jquery复选框全选/取消示例
Dec 30 Javascript
js如何获取object类型里的键值
Feb 18 Javascript
javascript制作的网页侧边弹出框思路及实现代码
May 21 Javascript
js获取内联样式的方法
Jan 27 Javascript
jQuery Form插件使用详解_动力节点Java学院整理
Jul 17 jQuery
纯js实现画一棵树的示例
Sep 05 Javascript
jQuery实现鼠标点击处心形漂浮的炫酷效果示例
Apr 12 jQuery
五分钟搞懂Vuex实用知识(小结)
Aug 12 Javascript
JS实现可控制的进度条
Mar 25 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
php自动跳转中英文页面
2008/07/29 PHP
浅析php中如何在有限的内存中读取大文件
2013/07/02 PHP
php实现水仙花数的4个示例分享
2014/04/08 PHP
jquery 得到当前页面高度和宽度的两个函数
2010/02/21 Javascript
jquery+ashx无刷新GridView数据显示插件(实现分页、排序、过滤功能)
2010/04/25 Javascript
JavaScript 继承机制的实现(待续)
2010/05/18 Javascript
js不完美解决click和dblclick事件冲突问题
2012/07/16 Javascript
JavaScript实现在数组中查找不同顺序排列的字符串
2014/09/26 Javascript
jQuery $命名冲突解决方案汇总
2014/11/13 Javascript
原生javascript实现图片弹窗交互效果
2015/01/12 Javascript
JS实现兼容各浏览器解析XML文档数据的方法
2015/06/01 Javascript
深入解读JavaScript中的Iterator和for-of循环
2015/07/28 Javascript
详解微信小程序 wx.uploadFile 的编码坑
2017/01/23 Javascript
解决vue中对象属性改变视图不更新的问题
2018/02/23 Javascript
解决IE11 vue +webpack 项目中数据更新后页面没有刷新的问题
2018/09/25 Javascript
用原生 JS 实现 innerHTML 功能实例详解
2019/04/03 Javascript
IE浏览器下JS脚本提交表单后,不能自动提示问题解决方法
2019/06/04 Javascript
环形加载进度条封装(Vue插件版和原生js版)
2019/12/04 Javascript
[28:57]EG vs VGJ.T 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/16 DOTA
Python入门篇之条件、循环
2014/10/17 Python
python简单获取本机计算机名和IP地址的方法
2015/06/03 Python
python编码总结(编码类型、格式、转码)
2016/07/01 Python
Python使用poplib模块和smtplib模块收发电子邮件的教程
2016/07/02 Python
python 对类的成员函数开启线程的方法
2019/01/22 Python
对python多线程SSH登录并发脚本详解
2019/02/14 Python
通过实例简单了解Python中yield的作用
2019/12/11 Python
Python自动化测试中yaml文件读取操作
2020/08/20 Python
Omio西班牙:全欧洲低价大巴、火车和航班搜索和比价
2017/02/11 全球购物
SheIn俄罗斯:时尚女装网上商店
2017/02/28 全球购物
美国转售二手商品的电子商务平台:BLINQ
2018/12/13 全球购物
如何查找和删除数据库中的重复数据
2014/11/05 面试题
党课学习思想汇报
2014/01/02 职场文书
学雷锋志愿服务月活动总结
2014/03/09 职场文书
房地产广告词大全
2014/03/19 职场文书
检讨书模板
2015/01/29 职场文书
2016年小学感恩节活动总结
2016/04/01 职场文书