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 相关文章推荐
jQuery控制图片的hover效果(smartRollover.js)
Mar 18 Javascript
jQuery阻止事件冒泡具体实现
Oct 11 Javascript
JQuery中Text方法用法实例分析
May 18 Javascript
JS多物体实现缓冲运动效果示例
Dec 20 Javascript
Javascript 编码约定(编码规范)
Mar 11 Javascript
js技巧之十几行的代码实现vue.watch代码
Jun 09 Javascript
JS中‘hello’与new String(‘hello’)引出的问题详解
Aug 14 Javascript
Vue代码整洁之去重方法整理
Aug 06 Javascript
layui加载数据显示loading加载完成loading消失的实例代码
Sep 23 Javascript
微信小程序实现单个卡片左滑显示按钮并防止上下滑动干扰功能
Dec 06 Javascript
vue element ui validate 主动触发错误提示操作
Sep 21 Javascript
vue 项目@change多个参数传值多个事件的操作
Jan 29 Vue.js
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
搜索和替换文件或目录的一个好类--很实用
2006/10/09 PHP
PHP框架Laravel的小技巧两则
2015/02/10 PHP
thinkPHP5.0框架URL访问方法详解
2017/03/18 PHP
PHP简单实现合并2个数字键数组值的方法
2017/05/30 PHP
详解php命令注入攻击
2019/04/06 PHP
php使用fputcsv实现大数据的导出操作详解
2020/02/27 PHP
JavaScript控制各种浏览器全屏模式的方法、属性和事件介绍
2014/04/03 Javascript
使用jquery操作session方法分享
2015/01/22 Javascript
jquery仿QQ登录账号选择下拉框效果
2016/03/22 Javascript
深入理解js数组的sort排序
2016/05/28 Javascript
浅谈js图片前端预览之filereader和window.URL.createObjectURL
2016/06/30 Javascript
jQuery实现注册会员时密码强度提示信息功能示例
2017/09/05 jQuery
微信小程序wx.getImageInfo()如何获取图片信息
2018/01/26 Javascript
vue中element组件样式修改无效的解决方法
2018/02/03 Javascript
通过cordova将vue项目打包为webapp的方法
2019/02/02 Javascript
Vue路由前后端设计总结
2019/08/06 Javascript
JS回调函数深入理解
2019/10/16 Javascript
Layui实现主窗口和Iframe层参数传递
2019/11/14 Javascript
js实现验证码功能
2020/07/24 Javascript
Python中线程编程之threading模块的使用详解
2015/06/23 Python
Python3 replace()函数使用方法
2018/03/19 Python
python 集合 并集、交集 Series list set 转换的实例
2018/05/29 Python
Python使用sort和class实现的多级排序功能示例
2018/08/15 Python
Python Multiprocessing多进程 使用tqdm显示进度条的实现
2019/08/13 Python
Python调用scp向服务器上传文件示例
2019/12/22 Python
如何向scrapy中的spider传递参数的几种方法
2020/11/18 Python
使用HTML5和CSS3表单验证功能
2017/05/05 HTML / CSS
乌克兰在线电子产品商店:MTA
2019/11/14 全球购物
Blue Nile蓝色尼罗河香港官网:世界最大在线钻石珠宝销售商
2020/05/07 全球购物
公司年会抽奖活动主持词
2014/03/31 职场文书
党的群众路线教育实践方案
2014/05/11 职场文书
2014年实验室工作总结
2014/12/03 职场文书
2014小学语文教学工作总结
2014/12/17 职场文书
工人先锋号申报材料
2014/12/29 职场文书
团委副书记工作总结
2015/08/14 职场文书
Win11查看设备管理器
2022/04/19 数码科技