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的遍历同id元素 并响应事件的代码
Jun 14 Javascript
js关闭当前页面(窗口)的几种方式总结
Mar 05 Javascript
D3.js 从P元素的创建开始(显示可加载数据)
Oct 30 Javascript
jQuery实现跟随鼠标运动图层效果的方法
Feb 02 Javascript
js微信分享API
Oct 11 Javascript
jQuery解析XML 详解及方法总结
Sep 28 Javascript
jQuery的中 is(':visible') 解析及用法(必看)
Feb 12 Javascript
JQuery Ajax 异步操作之动态添加节点功能
May 24 jQuery
聊聊那些使用前端Javascript实现的机器学习类库
Sep 18 Javascript
node中使用es6/7/8(支持性与性能)
Mar 28 Javascript
node学习笔记之读写文件与开启第一个web服务器操作示例
May 29 Javascript
详解JavaScript 事件流
Sep 02 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+MYSQL开发工具及资源收藏
2007/01/02 PHP
简单介绍PHP的责任链编程模式
2015/08/11 PHP
PHP登录(ajax提交数据和后台校验)实例分享
2016/12/29 PHP
详解Yii2高级版引入bootstrap.js的一个办法
2017/03/21 PHP
Laravel 5.2 文档 数据库 ―― 起步介绍
2019/10/21 PHP
Laravel 集成微信用户登录和绑定的实现
2019/12/27 PHP
判断是否输入完毕再激活提交按钮
2006/06/26 Javascript
Javascript实现的分页函数
2006/12/22 Javascript
JQuery 常用方法基础教程
2009/02/06 Javascript
Javascript中的this绑定介绍
2011/09/22 Javascript
完美兼容各大浏览器的jQuery插件实现图片切换特效
2014/12/12 Javascript
JavaScript设计模式之建造者模式介绍
2014/12/28 Javascript
javascript实现随时变化着的背景颜色
2015/04/02 Javascript
详细探究ES6之Proxy代理
2016/07/22 Javascript
Highcharts入门之简介
2016/08/02 Javascript
探讨跨域请求资源的几种方式(总结)
2016/12/02 Javascript
微信小程序 闭包写法详细介绍
2016/12/14 Javascript
Bootstrap常用组件学习(整理)
2017/03/24 Javascript
浅谈vue首屏加载优化
2018/06/28 Javascript
nodejs基础之buffer缓冲区用法分析
2018/12/26 NodeJs
详解如何在JS代码中消灭for循环
2019/12/11 Javascript
[02:33]2018DOTA2亚洲邀请赛赛前采访——LGD
2018/04/04 DOTA
Python创建普通菜单示例【基于win32ui模块】
2018/05/09 Python
pandas每次多Sheet写入文件的方法
2018/12/10 Python
python字典改变value值方法总结
2019/06/21 Python
Django中Middleware中的函数详解
2019/07/18 Python
Python爬虫之Selenium中frame/iframe表单嵌套页面
2020/12/04 Python
CSS3中的@keyframes关键帧动画的选择器绑定
2016/06/13 HTML / CSS
印度最好的在线药品订购网站:PharmEasy
2018/11/30 全球购物
迅雷Cued工作心得体会
2014/01/27 职场文书
退休教师欢送会主持词
2014/03/31 职场文书
工地安全标语
2014/06/07 职场文书
校本教研活动总结
2014/07/01 职场文书
初婚未育证明样本
2014/10/24 职场文书
工厂门卫岗位职责
2015/04/13 职场文书
Springboot-cli 开发脚手架,权限认证,附demo演示
2022/04/28 Java/Android