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 相关文章推荐
javascript 简练的几个函数
Aug 29 Javascript
jquery实现瀑布流效果分享
Mar 26 Javascript
JS实现判断滚动条滚到页面底部并执行事件的方法
Dec 18 Javascript
jQuery中prepend()方法用法实例
Dec 25 Javascript
JS实现表格数据各种搜索功能的方法
Mar 03 Javascript
javascript中JSON对象与JSON字符串相互转换实例
Jul 11 Javascript
Bootstrap框架结合jQuery仿百度换肤功能实例解析
Sep 17 Javascript
input框中的name和id的区别
Nov 16 Javascript
JS实现手写parseInt的方法示例
Sep 24 Javascript
利用hasOwnProperty给数组去重的面试题分享
Nov 05 Javascript
详解基于Vue/React项目的移动端适配方案
Aug 23 Javascript
浅析 Vue 3.0 的组装式 API(一)
Aug 31 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
ajax+php控制所有后台函数调用
2015/07/15 PHP
[原创]用javascript实现检测指定目录是否存在的方法
2008/01/12 Javascript
JQuery在光标位置插入内容的实现代码
2010/06/18 Javascript
jQuery学习笔记之toArray()
2014/06/09 Javascript
JavaScript获得页面base标签中url的方法
2015/04/03 Javascript
javascript笛卡尔积算法实现方法
2015/04/08 Javascript
JSON+Jquery省市区三级联动
2016/01/13 Javascript
JavaScript提高网站性能优化的建议(二)
2016/07/24 Javascript
关于input全选反选恶心的异常情况
2016/07/24 Javascript
微信小程序 form组件详解
2016/10/25 Javascript
JavaScript trim 实现去除字符串首尾指定字符的简单方法
2016/12/27 Javascript
原生js实现弹出层效果
2017/01/20 Javascript
vue小图标favicon不显示的解决方案
2017/09/19 Javascript
JavaScript html5 canvas实现图片上画超链接
2017/10/20 Javascript
详解基于vue-cli优化的webpack配置
2017/11/06 Javascript
nodejs更改项目端口号的方法
2018/05/13 NodeJs
Vue项目引进ElementUI组件的方法
2018/11/11 Javascript
NProgress显示顶部进度条效果及使用详解
2019/09/21 Javascript
vue.js实现三级菜单效果
2019/10/19 Javascript
vue实践---根据不同环境,自动转换请求的url地址操作
2020/09/21 Javascript
对python中的logger模块全面讲解
2018/04/28 Python
python format 格式化输出方法
2018/07/16 Python
pygame实现雷电游戏雏形开发
2018/11/20 Python
详解python tkinter 图片插入问题
2020/09/03 Python
adidas旗下高尔夫装备供应商:TaylorMade Golf(泰勒梅高尔夫)
2016/08/28 全球购物
音乐学院硕士生的自我评价分享
2013/11/01 职场文书
蔬菜基地的创业计划书
2014/01/06 职场文书
社会实践先进工作者事迹材料
2014/05/06 职场文书
乡镇党建工作汇报材料
2014/08/14 职场文书
初中信息技术教学计划
2015/01/22 职场文书
医学生自荐信范文(2016精选篇)
2016/01/28 职场文书
《鸟的天堂》教学反思
2016/02/19 职场文书
Python标准库之typing的用法(类型标注)
2021/06/02 Python
pytorch 预训练模型读取修改相关参数的填坑问题
2021/06/05 Python
Python Pandas pandas.read_sql函数实例用法
2021/06/21 Python
Vue操作Storage本地化存储
2022/04/29 Vue.js