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实现动画效果的简单实例
Jan 27 Javascript
JavaScript实现计算字符串中出现次数最多的字符和出现的次数
Mar 12 Javascript
JavaScript实现广告的关闭与显示效果实例
Jul 02 Javascript
AngularJS使用angular-formly进行表单验证
Dec 27 Javascript
基于react框架使用的一些细节要点的思考
May 31 Javascript
EasyUI的TreeGrid的过滤功能的解决思路
Aug 08 Javascript
JavaScript实现滑动导航栏效果
Aug 30 Javascript
深入浅析AngularJs模版与v-bind
Jul 06 Javascript
JS实现简单日历特效
Jan 03 Javascript
vue下canvas裁剪图片实例讲解
Apr 16 Javascript
vue 使用async写数字动态加载效果案例
Jul 18 Javascript
JavaScript实现简单日历效果
Sep 11 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
php5编程中的异常处理详细方法介绍
2008/07/29 PHP
Smarty中调用FCKeditor的方法
2014/10/27 PHP
PHP里8个鲜为人知的安全函数分析
2014/12/09 PHP
php使用ftp实现文件上传与下载功能
2017/07/21 PHP
学习jquery必备 api中英文对照的chm手册 下载
2007/05/03 Javascript
Javascript 中的类和闭包
2010/01/08 Javascript
jquery select下拉框操作的一些说明
2010/04/02 Javascript
js获取客户端外网ip的简单实例
2013/11/21 Javascript
简介alert()与console.log()的不同
2015/08/26 Javascript
js获取json中key所对应的value值的简单方法
2020/06/17 Javascript
谈谈VUE种methods watch和compute的区别和联系
2017/08/01 Javascript
JavaScript寄生组合式继承实例详解
2018/01/06 Javascript
浅谈Node.js爬虫之网页请求模块
2018/01/11 Javascript
bootstrap 路径导航 分页 进度条的实例代码
2018/08/06 Javascript
jquery 动态遍历select 赋值的实例
2018/09/12 jQuery
详解Vue项目部署遇到的问题及解决方案
2019/01/11 Javascript
vue项目中全局引入1个.scss文件的问题解决
2019/08/01 Javascript
Node.js使用MongoDB的ObjectId作为查询条件的方法
2019/09/10 Javascript
Vue执行方法,方法获取data值,设置data值,方法传值操作
2020/08/05 Javascript
js+canvas实现画板功能
2020/09/13 Javascript
Python中的字典遍历备忘
2015/01/17 Python
django接入新浪微博OAuth的方法
2015/06/29 Python
详解Python中where()函数的用法
2018/03/27 Python
python中返回矩阵的行列方法
2018/04/04 Python
对python读取zip压缩文件里面的csv数据实例详解
2019/02/08 Python
python 执行终端/控制台命令的例子
2019/07/12 Python
Python数据可视化 pyecharts实现各种统计图表过程详解
2019/08/15 Python
Python作用域与名字空间原理详解
2020/03/21 Python
vscode配置anaconda3的方法步骤
2020/08/08 Python
如何利用Python给自己的头像加一个小国旗(小月饼)
2020/10/02 Python
极简的HTML5模版
2015/07/09 HTML / CSS
正隆泰信息技术有限公司上机题
2012/06/14 面试题
12.4全国法制宣传日活动方案
2014/11/02 职场文书
2014年幼儿园后勤工作总结
2014/11/10 职场文书
2016新教师岗前培训心得体会
2016/01/08 职场文书
TV动画《间谍过家家》公开PV
2022/03/20 日漫