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 Dialog的内存泄露问题解决方法
Jun 18 Javascript
javascript限制文本框输入值类型的方法
May 07 Javascript
Javascript中的arguments对象
Jun 20 Javascript
Angularjs使用directive自定义指令实现attribute继承的方法详解
Aug 05 Javascript
jQuery判断是否存在滚动条的简单方法
Sep 17 Javascript
jQuery EasyUI 右键菜单--关闭标签/选项卡的简单实例
Oct 10 Javascript
jQuery实现获取table中鼠标click点击位置行号与列号的方法
Oct 09 jQuery
Vue进度条progressbar组件功能
Apr 17 Javascript
vue权限管理系统的实现代码
Jan 17 Javascript
基于vue的验证码组件的示例代码
Jan 22 Javascript
JS前端模块化原理与实现方法详解
Mar 17 Javascript
vue+render+jsx实现可编辑动态多级表头table的实例代码
Apr 01 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环境配置 php5 mysql5 apache2 phpmyadmin安装与配置
2006/11/17 PHP
探讨PHP调用时间格式的参数详解
2013/06/06 PHP
使用XHGui来测试PHP性能的教程
2015/07/03 PHP
php中关于长度计算容易混淆的问题分析
2016/05/27 PHP
php 运算符与表达式详细介绍
2016/11/30 PHP
php设计模式之适配器模式原理、用法及注意事项详解
2019/09/24 PHP
laravel5.2表单验证,并显示错误信息的实例
2019/09/29 PHP
jquery动态加载js/css文件方法(自写小函数)
2014/10/11 Javascript
深入理解javascript严格模式(Strict Mode)
2014/11/28 Javascript
Boostrap模态窗口的学习小结
2016/03/28 Javascript
json传值以及ajax接收详解
2016/05/24 Javascript
JS获取字符串实际长度(包含汉字)的简单方法
2016/08/11 Javascript
Vue-resource实现ajax请求和跨域请求示例
2017/02/23 Javascript
vue实现简单表格组件实例详解
2017/04/16 Javascript
微信小程序中input标签详解及简单实例
2017/05/18 Javascript
详解基于vue-router的动态权限控制实现方案
2017/09/28 Javascript
浅谈AngularJs 双向绑定原理(数据绑定机制)
2017/12/07 Javascript
vue中的数据绑定原理的实现
2018/07/02 Javascript
微信小程序首页的分类功能和搜索功能的实现思路及代码详解
2018/09/11 Javascript
vue 弹框产生的滚动穿透问题的解决
2018/09/21 Javascript
vue 百度地图(vue-baidu-map)绘制方向箭头折线实例代码详解
2020/04/28 Javascript
nodejs中的异步编程知识点详解
2021/01/17 NodeJs
[14:20]刀塔大凶女神互压各路奇葩屌丝
2014/05/16 DOTA
Python实现Linux的find命令实例分享
2017/06/04 Python
Python中pandas模块DataFrame创建方法示例
2018/06/20 Python
pyqt5 键盘监听按下enter 就登陆的实例
2019/06/25 Python
Django之提交表单与前后端交互的方法
2019/07/19 Python
Python 爬取必应壁纸的实例讲解
2020/02/24 Python
django有哪些好处和优点
2020/09/01 Python
用sleep间隔进行python反爬虫的实例讲解
2020/11/30 Python
PyQt5通过信号实现MVC的示例
2021/02/06 Python
HTML5 客户端数据库简易使用:IndexedDB
2019/12/19 HTML / CSS
小学教师师德师风自我评价
2015/03/04 职场文书
团拜会主持词
2015/07/04 职场文书
总经理聘用协议书
2015/09/21 职场文书
Javascript 解构赋值详情
2021/11/17 Javascript