防止重复发送 Ajax 请求


Posted in Javascript onFebruary 15, 2017

要考虑并理解 success, complete, error, timeout 这些事件的区别,并注册正确的事件,一旦失误,功能将不再可用;

不可避免地比普通流程要要多注册一个 complete 事件;

恢复状态的代码很容易和不相干的代码混合在一起;

推荐用主动查询状态的方式(A、B,jQuery 为例)或工具函数的方式(C、D)来去除重复操作,并提供一些例子作为参考:

A. 独占型提交

只允许同时存在一次提交操作,并且直到本次提交完成才能进行下一次提交。

module.submit = function() {
 if (this.promise_.state() === 'pending') {
 return
 }
 return this.promise_ = $.post('/api/save')
}

B. 贪婪型提交

无限制的提交,但是以最后一次操作为准;亦即需要尽快给出最后一次操作的反馈,而前面的操作结果并不重要。

module.submit = function() {
 if (this.promise_.state() === 'pending') {
 this.promise_.abort()
 }
 // todo
}

比如某些应用的条目中,有一些进行类似「喜欢」或「不喜欢」操作的二态按钮。如果按下后不立即给出反馈,用户的目光焦点就可能在那个按钮上停顿许久;如果按下时即时切换按钮的状态,再在程序上用 abort 来实现积极的提交,这样既能提高用户体验,还能降低服务器压力,皆大欢喜。

C. 节制型提交

无论提交如何频繁,任意两次有效提交的间隔时间必定会大于或等于某一时间间隔;即以一定频率提交。

module.submit = throttle(150, function() {
 // todo
})

如果客户发送每隔100毫秒发送过来10次请求,此模块将只接收其中6个(每个在时间线上距离为150毫秒)进行处理。

这也是解决查询冲突的一种可选手段,比如以知乎草稿举例,仔细观察可以发现:

编辑器的 blur 事件会立即触发保存;

保存按钮的 click 事件也会立即触发保存;

但是存在一种情况会使这两个事件在数毫秒内连续发生——当焦点在编辑器内部,并且直接去点击保存按钮——这时用 throttle 来处理是可行的。

另外还有一些事件处理会很频繁地使用 throttle,如: resize、scroll、mousemove。

D. 懒惰型提交

任意两次提交的间隔时间,必须大于一个指定时间,才会促成有效提交;即不给休息不干活。

module.submit = debounce(150, function() {
 // todo
})

还是以知乎草稿举例,当在编辑器内按下 ctrl + s 时,可以手动保存草稿;如果你连按,程序会表示不理解为什么你要连按,只有等你放弃连按,它才会继续。

============

更多记忆中的例子

方式 C 和 方式 D 有时更加通用,比如这些情况:

游戏中你捡到一把威力强大的高速武器,为了防止你的子弹在屏幕上打成一条直线,可以 throttle 来控制频率;

在弹幕型游戏里,为了防止你把射击键夹住来进行无脑游戏,可以用 debounce 来控制频率;

在编译任务里,守护进程监视了某一文件夹里所有的文件(如任一文件的改变都可以触发重新编译,一次执行就需要2秒),但某种操作能够瞬间造成大量文件改变(如 git checkout),这时一个简单的 debounce 可以使编译任务只执行一次。

而方式 C 甚至可以和方式 B 组合使用,比如自动完成组件(Google 首页的搜索就是):

当用户快速输入文本时(特别是打字能手),可以 throttle keypress 事件处理函数,以指定时间间隔来提取文本域的值,然后立即进行新的查询;

当新的查询需要发送,但上一个查询还没返回结果时,可以 abort 未完成的查询,并立即发送新查询;

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
jquery 清空file域示例(兼容个浏览器)
Oct 11 Javascript
js实现遮罩层划出效果是生成div而不是显示
Jul 29 Javascript
JavaScript中setFullYear()方法的使用详解
Jun 11 Javascript
一步步教大家编写酷炫的导航栏js+css实现
Mar 14 Javascript
jQuery中select与datalist制作下拉菜单时的区别浅析
Dec 30 Javascript
Angular2搜索和重置按钮过场动画
May 24 Javascript
vue代理和跨域问题的解决
Jul 18 Javascript
基于vue-upload-component封装一个图片上传组件的示例
Oct 16 Javascript
vue-cli3+typescript初体验小结
Feb 28 Javascript
JavaScript实现选项卡效果的分析及步骤
Apr 16 Javascript
三步实现ionic3点击退出app程序
Sep 17 Javascript
vue调用本地摄像头实现拍照功能
Aug 14 Javascript
Input文本框随着输入内容多少自动延伸的实现
Feb 15 #Javascript
利用Jquery实现几款漂亮实用的时间轴(附示例代码)
Feb 15 #Javascript
js记录点击某个按钮的次数-刷新次数为初始状态的实例
Feb 15 #Javascript
Canvas 绘制粒子动画背景
Feb 15 #Javascript
jQuery插件jquery.kxbdmarquee.js实现无缝滚动效果
Feb 15 #Javascript
js控制按钮,防止频繁点击响应的实例
Feb 15 #Javascript
js代码延迟一定时间后执行一个函数的实例
Feb 15 #Javascript
You might like
php 魔术函数使用说明
2010/02/21 PHP
PHP 第一节 php简介
2012/04/28 PHP
关于PHP session 存储方式的详细介绍
2013/06/25 PHP
用PHP的反射实现委托模式的讲解
2019/03/22 PHP
PHP网页缓存技术优点及代码实例
2020/07/29 PHP
浅谈javascript 归并方法
2015/01/21 Javascript
使用jquery实现鼠标滑过弹出更多相关信息层附源码下载
2015/11/23 Javascript
探究Javascript模板引擎mustache.js使用方法
2016/01/26 Javascript
JavaScript实现时间表动态效果
2017/07/15 Javascript
jQuery remove()过滤被删除的元素(推荐)
2017/07/18 jQuery
详解angularjs获取元素以及angular.element()用法
2017/07/25 Javascript
Bootstrap与Angularjs的模态框实例代码
2017/08/03 Javascript
详解基于 axios 的 Vue 项目 http 请求优化
2017/09/04 Javascript
Vue2.0中集成UEditor富文本编辑器的方法
2018/03/03 Javascript
vue中slot(插槽)的介绍与使用
2018/11/12 Javascript
js实现倒计时器自定义时间和暂停
2019/02/25 Javascript
Python3处理HTTP请求的实例
2018/05/10 Python
Python3日期与时间戳转换的几种方法详解
2019/06/04 Python
pandas读取CSV文件时查看修改各列的数据类型格式
2019/07/07 Python
Python Excel vlookup函数实现过程解析
2020/06/22 Python
Python基于yaml文件配置logging日志过程解析
2020/06/23 Python
CSS3 真的会替代 SCSS 吗
2021/03/09 HTML / CSS
韩国女装NO.1网店:STYLENANDA
2016/09/16 全球购物
Forever 21美国官网:美国标志性快时尚品牌
2017/02/20 全球购物
档案室主任岗位职责
2014/02/12 职场文书
21岁生日感言
2014/02/27 职场文书
小学数学课后反思
2014/04/23 职场文书
《称象》教学反思
2014/04/25 职场文书
2014年检验员工作总结
2014/11/19 职场文书
感谢信范文大全
2015/01/23 职场文书
2014年度个人工作总结范文
2015/03/09 职场文书
人口与计划生育责任书
2015/05/09 职场文书
小孩不笨观后感
2015/06/03 职场文书
个人合作协议范本
2015/08/06 职场文书
秀!学妹看见都惊呆的Python小招数!【详细语言特性使用技巧】
2021/04/27 Python
python3.7.2 tkinter entry框限定输入数字的操作
2021/05/22 Python