Javascript异步执行不按顺序解决方案


Posted in Javascript onApril 30, 2020

案例分析:

比如执行懒加载时候,onscroll 事件触发多次事件时候会调用多次 ajax 回调事件,由于每个事件返回先后次序并不能保证和触发前一致,所以在数据响应返回后所添加的数据顺序就很在 push 到数组上顺序不一致。

例子1:

var res = [];
   function response(data) {
     res.push( data );
}
// ajax(..)是某个库中提供的某个Ajax函数 
ajax( "http://some.url.1", response ); 
ajax( "http://some.url.2", response );

这里的并发“进程”是这两个用来处理 Ajax 响应的 response() 调用。它们可能以任意顺 序运行。

我们假定期望的行为是 res[0] 中放调用 "http://some.url.1" 的结果,res[1] 中放调用 "http://some.url.2" 的结果。有时候可能是这样,但有时候却恰好相反,这要视哪个调 用先完成而定。

这种不确定性很有可能就是一个竞态条件 bug。

解决办法

var res = [];
function response(data) {
     if (data.url == "http://some.url.1") {
       res[0] = data;
     }
     else if (data.url == "http://some.url.2") {
       res[1] = data;
     } 
}
// ajax(..)是某个库中提供的某个Ajax函数 
ajax( "http://some.url.1", response ); 
ajax( "http://some.url.2", response );

不管哪一个 Ajax 响应先返回,我们都要通过查看 data.url(当然,假定从服务器总会返 回一个!)判断应该把响应数据放在 res 数组中的什么位置上。res[0] 总是包含 "http:// some.url.1" 的结果,res[1] 总是包含 "http://some.url.2" 的结果。通过简单的协调,就 避免了竞态条件引起的不确定性。

例子2:

var a, b;
   function foo(x) {
     a = x * 2;
     baz(); 
   }
   function bar(y) {
     b = y * 2;
     baz(); 
   }
   function baz() {
     console.log(a + b);
   }
// ajax(..)是某个库中的某个Ajax函数 
ajax( "http://some.url.1", foo ); 
ajax( "http://some.url.2", bar );

在这个例子中,无论 foo() 和 bar() 哪一个先被触发,总会使 baz() 过早运行(a 或者 b 仍处 于未定义状态);但对 baz() 的第二次调用就没有问题,因为这时候 a 和 b 都已经可用了。

要解决这个问题有多种方法。这里给出了一种简单方法:

var a, b;
function foo(x) {
     a = x * 2;
     if (a && b) {
       baz();
     } 
}
function bar(y) {
     b = y * 2;
     if (a && b) {
       baz();
     } 
}
function baz() {
     console.log( a + b );
}
// ajax(..)是某个库中的某个Ajax函数 
ajax( "http://some.url.1", foo );
ajax( "http://some.url.2", bar );

包裹baz()调用的条件判断if (a && b)传统上称为门(gate),我们虽然不能确定a和b 到达的顺序,但是会等到它们两个都准备好再进一步打开门(调用 baz())。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
载入进度条 效果
Jul 08 Javascript
在修改准备发的批量美化select+可修改select时,在非IE下发现了几个问题
Jan 09 Javascript
jQuery点击后一组图片左右滑动的实现代码
Aug 16 Javascript
js获取当月最后一天实例代码
Nov 19 Javascript
jQuery删除节点的三个方法即remove()detach()和empty()
Dec 27 Javascript
关于Javascript 对象(object)的prototype
May 09 Javascript
javascript学习笔记(六)数据类型和JSON格式
Oct 08 Javascript
jQuery 3.0十大新特性最终版发布
Jul 14 Javascript
jquery对象与DOM对象转化
Feb 08 Javascript
WebSocket实现简单客服聊天系统
May 12 Javascript
Vue-Cli 3.0 中配置高德地图的两种方式
Jun 19 Javascript
微信小程序中target和currentTarget的区别小结
Nov 06 Javascript
JS判断浏览器类型与操作系统的方法分析
Apr 30 #Javascript
JavaScript自定义超时API代码实例
Apr 30 #Javascript
javascript 模块依赖管理的本质深入详解
Apr 30 #Javascript
JavaScript find()方法及返回数据实例
Apr 30 #Javascript
js this 绑定机制深入详解
Apr 30 #Javascript
JS 图片压缩原理与实现方法详解
Apr 29 #Javascript
详解Vue3 Composition API中的提取和重用逻辑
Apr 29 #Javascript
You might like
全国FM电台频率大全 - 1 北京市
2020/03/11 无线电
php删除txt文件指定行及按行读取txt文档数据的方法
2017/01/30 PHP
PHP curl批处理及多请求并发实现方法分析
2018/08/15 PHP
thinkphp5框架前后端分离项目实现分页功能的方法分析
2019/10/08 PHP
一个JS翻页效果
2007/07/23 Javascript
一个关于jqGrid使用的小例子(行按钮)
2011/11/04 Javascript
用js实现小球的自由移动代码
2013/04/22 Javascript
将json当数据库一样操作的javascript lib
2013/10/28 Javascript
JavaScript类型检测之typeof 和 instanceof 的缺陷与优化
2016/01/13 Javascript
JS刷新父窗口的几种方式小结(推荐)
2016/11/09 Javascript
如何解决jQuery EasyUI 已打开Tab重新加载问题
2016/12/19 Javascript
js中的事件委托或是事件代理使用详解
2017/06/23 Javascript
vue监听scroll的坑的解决方法
2017/09/07 Javascript
给vue项目添加ESLint的详细步骤
2017/09/29 Javascript
浅谈Node.js CVE-2017-14849 漏洞分析(详细步骤)
2017/11/10 Javascript
node.js读取Excel数据(下载图片)的方法示例
2018/08/02 Javascript
vue中使用v-for时为什么不能用index作为key
2020/04/04 Javascript
JavaScript或jQuery 获取option value值方法解析
2020/05/12 jQuery
python不带重复的全排列代码
2013/08/13 Python
Python重新引入被覆盖的自带function
2014/07/16 Python
Python图像处理之颜色的定义与使用分析
2019/01/03 Python
python虚拟环境的安装和配置(virtualenv,virtualenvwrapper)
2019/08/09 Python
Python 依赖库太多了该如何管理
2019/11/08 Python
python 实现屏幕录制示例
2019/12/23 Python
Python 通过爬虫实现GitHub网页的模拟登录的示例代码
2020/08/17 Python
python操作ini类型配置文件的实例教程
2020/10/30 Python
python之pygame模块实现飞机大战完整代码
2020/11/29 Python
Python实现粒子群算法的示例
2021/02/14 Python
使用jquery实现HTML5响应式导航菜单教程
2014/04/02 HTML / CSS
JINS眼镜官方网站:日本最大的眼镜邮购
2016/10/14 全球购物
物流专业大学生的自我鉴定
2013/11/13 职场文书
应届生的求职推荐信范文
2013/11/30 职场文书
乡镇民主生活会发言材料
2014/10/20 职场文书
拒绝盗图!教你怎么用python给图片加水印
2021/06/04 Python
spring cloud eureka 服务启动失败的原因分析及解决方法
2022/03/17 Java/Android
windows server2008 开启端口的实现方法
2022/06/25 Servers