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 相关文章推荐
Javascript的闭包
Dec 31 Javascript
javscript对象原型的一些看法
Sep 19 Javascript
jQuery给多个不同元素添加class样式的方法
Mar 26 Javascript
JS实现点击Radio动态更新table数据
Jul 18 Javascript
使用javaScript实现鼠标拖拽事件
Apr 03 Javascript
Vuex实现计数器以及列表展示效果
Mar 10 Javascript
详解VUE 对element-ui中的ElTableColumn扩展
Mar 28 Javascript
关于node-bindings无法在Electron中使用的解决办法
Dec 18 Javascript
微信小程序调用天气接口并且渲染在页面过程详解
Jun 24 Javascript
vue:el-input输入时限制输入的类型操作
Aug 05 Javascript
JavaScript前后端JSON使用方法教程
Nov 23 Javascript
JS实现超级好看的鼠标小尾巴特效
Dec 01 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
php获取当前网址url并替换参数或网址的方法
2010/06/06 PHP
在PHP中使用curl_init函数的说明
2010/11/02 PHP
两千行代码的PHP学习笔记汇总
2014/10/05 PHP
php准确获取文件MIME类型的方法
2015/06/17 PHP
PHP数据库表操作的封装类及用法实例详解
2016/07/12 PHP
php PDO实现的事务回滚示例
2017/03/23 PHP
php基于session锁防止阻塞请求的方法分析
2017/08/07 PHP
JS宝典学习笔记(下)
2007/01/10 Javascript
jQuery学习3:操作元素属性和特性
2010/02/07 Javascript
JS刷新框架外页面七种实现代码
2013/02/18 Javascript
在javascript中如何得到中英文混合字符串的长度
2014/01/17 Javascript
AngularJS语法详解(续)
2015/01/23 Javascript
深入理解JavaScript系列(30):设计模式之外观模式详解
2015/03/03 Javascript
js实现继承的5种方式
2015/12/01 Javascript
原生js实现jquery函数animate()动画效果的简单实例
2016/08/21 Javascript
angularjs 源码解析之injector
2016/08/22 Javascript
node学习记录之搭建web服务器教程
2017/02/16 Javascript
vue2.0 + element UI 中 el-table 数据导出Excel的方法
2018/03/02 Javascript
微信小程序与后台PHP交互的方法实例分析
2018/12/10 Javascript
elementUI 动态生成几行几列的方法示例
2019/07/11 Javascript
Vue路由前后端设计总结
2019/08/06 Javascript
将图片文件嵌入到wxpython代码中的实现方法
2014/08/11 Python
利用Python代码实现数据可视化的5种方法详解
2018/03/25 Python
Python自动化之数据驱动让你的脚本简洁10倍【推荐】
2019/06/04 Python
python自定义时钟类、定时任务类
2021/02/22 Python
python绘制动态曲线教程
2020/02/24 Python
keras 回调函数Callbacks 断点ModelCheckpoint教程
2020/06/18 Python
Flask-SocketIO服务端安装及使用代码示例
2020/11/26 Python
CSS3 渐变(Gradients)之CSS3 径向渐变
2016/07/08 HTML / CSS
Clearly澳大利亚:购买眼镜、太阳镜和隐形眼镜
2018/04/26 全球购物
美体小铺印度官网:The Body Shop印度
2019/10/17 全球购物
SQL语言面试题
2013/08/27 面试题
请解释流与文件有什么不同
2016/07/29 面试题
学校门卫岗位职责范本
2014/06/30 职场文书
租车协议书
2015/01/27 职场文书
2015年银行柜员工作总结报告
2015/04/01 职场文书