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 相关文章推荐
通过AJAX的JS、JQuery两种方式解析XML示例介绍
Sep 23 Javascript
验证码在IE中不刷新而谷歌等浏览器正常的解决方案
Mar 18 Javascript
JavaScript常用脚本汇总(二)
Mar 04 Javascript
JS实现日期时间动态显示的方法
Dec 07 Javascript
jQuery EasyUi实战教程之布局篇
Jan 26 Javascript
javascript中数组(Array)对象和字符串(String)对象的常用方法总结
Dec 15 Javascript
基于JS对象创建常用方式及原理分析
Jun 28 Javascript
利用Vue.js实现求职在线之职位查询功能
Jul 03 Javascript
Angular利用trackBy提升性能的方法
Jan 26 Javascript
vue+elementUI组件table实现前端分页功能
Nov 15 Javascript
详解Vue的ref特性的使用
Jan 24 Javascript
JS实现烟花爆炸效果
Mar 10 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
笑谈配置,使用Smarty技术
2007/01/04 PHP
详解YII关联查询
2016/01/10 PHP
Yii数据库缓存实例分析
2016/03/29 PHP
laravel框架中路由设置,路由参数和路由命名实例分析
2019/11/23 PHP
通过代码实例解析PHP session工作原理
2020/12/11 PHP
createElement与createDocumentFragment的点点区别小结
2011/12/19 Javascript
Jquery 跨域访问 Lightswitch OData Service的方法
2013/09/11 Javascript
JS自调用匿名函数具体实现
2014/02/11 Javascript
删除Javascript Object中间的key
2014/11/18 Javascript
浅谈Javascript中深复制
2014/12/01 Javascript
javascript实现修改微信分享的标题内容等
2014/12/11 Javascript
jquery处理页面弹出层查询数据等待操作实例
2015/03/25 Javascript
js事件冒泡与事件捕获详解
2017/02/20 Javascript
js实现图片懒加载效果
2017/07/17 Javascript
Vue实现typeahead组件功能(非常靠谱)
2017/08/26 Javascript
浅谈vuex之mutation和action的基本使用
2017/08/29 Javascript
详解Vue开发微信H5微信分享签名失败问题解决方案
2018/08/09 Javascript
详解基于electron制作一个node压缩图片的桌面应用
2019/01/29 Javascript
vue实现购物车抛物线小球动画效果的方法详解
2019/02/13 Javascript
JavaScript简易计算器制作
2020/01/17 Javascript
vue中使用vue-pdf的方法详解
2020/09/05 Javascript
vuex的数据渲染与修改浅析
2020/11/26 Vue.js
用PyQt进行Python图形界面的程序的开发的入门指引
2015/04/14 Python
Python的Django框架中模板碎片缓存简介
2015/07/24 Python
Python正则表达式常用函数总结
2017/06/24 Python
python opencv 直方图反向投影的方法
2018/02/24 Python
Python3.5字符串常用操作实例详解
2019/05/01 Python
完美解决TensorFlow和Keras大数据量内存溢出的问题
2020/07/03 Python
Python Charles抓包配置实现流程图解
2020/09/29 Python
Django web自定义通用权限控制实现方法
2020/11/24 Python
大学生职业规划范文:象牙塔生活的四年计划
2014/01/14 职场文书
医院义诊活动总结
2014/07/04 职场文书
个人纪律作风整改措施思想汇报
2014/10/12 职场文书
国王的演讲观后感
2015/06/03 职场文书
描述鲁迅的名言整理,一生受用
2019/08/08 职场文书
教你用eclipse连接mysql数据库
2021/04/22 MySQL