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 新手24条实用建议[TUTS+]
Jun 21 Javascript
extjs 学习笔记(一) 一些基础知识
Oct 13 Javascript
解决IE6的PNG透明JS插件使用介绍
Apr 17 Javascript
JS cookie中文乱码解决方法
Jan 28 Javascript
AngularJS 过滤器(自带和自建)详解
Sep 19 Javascript
js实现点击按钮弹出上传文件的窗口
Dec 23 Javascript
使用vue.js2.0 + ElementUI开发后台管理系统详细教程(一)
Jan 21 Javascript
利用js查找数组中指定元素并返回该元素的所有索引示例
Mar 29 Javascript
Angular 数据请求的实现方法
May 07 Javascript
vuex与组件联合使用的方法
May 10 Javascript
Angular ElementRef简介及其使用
Oct 01 Javascript
jQuery实现广告显示和隐藏动画
Jul 04 jQuery
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定时删除文件夹下文件(清理缓存文件)
2013/01/23 PHP
PHP实现网站应用微信登录功能详解
2019/04/11 PHP
PHP+fiddler抓包采集微信文章阅读数点赞数的思路详解
2019/12/20 PHP
JavaScript中的运算符种类及其规则介绍
2013/09/26 Javascript
javascript阻止浏览器后退事件防止误操作清空表单
2013/11/22 Javascript
JS验证邮箱格式是否正确的代码
2013/12/05 Javascript
js实时获取并显示当前时间的方法
2015/07/31 Javascript
Javascript json object 与string 相互转换的简单实现
2016/09/27 Javascript
Bootstrap select下拉联动(jQuery cxselect)
2017/01/04 Javascript
Vue声明式渲染详解
2017/05/17 Javascript
vue v-on监听事件详解
2017/05/17 Javascript
详解在WebStorm中添加Vue.js单文件组件的高亮及语法支持
2017/10/21 Javascript
详解JS函数stack size计算方法
2018/06/18 Javascript
node.js基于socket.io快速实现一个实时通讯应用
2019/04/23 Javascript
通过javascript实现段落的收缩与展开
2019/06/26 Javascript
微信小程序scroll-view隐藏滚动条的方法详解
2020/03/25 Javascript
vue 需求 data中的数据之间的调用操作
2020/08/05 Javascript
python实现ip查询示例
2014/03/26 Python
Python写的Tkinter程序屏幕居中方法
2015/03/10 Python
Python数据分析之获取双色球历史信息的方法示例
2018/02/03 Python
python-str,list,set间的转换实例
2018/06/27 Python
python中dir()与__dict__属性的区别浅析
2018/12/10 Python
Python 从一个文件中调用另一个文件的类方法
2019/01/10 Python
详解Python使用Plotly绘图工具,绘制甘特图
2019/04/02 Python
详解Python打包分发工具setuptools
2019/08/05 Python
详解java调用python的几种用法(看这篇就够了)
2020/12/10 Python
欧迪办公美国官网:Office Depot
2016/08/22 全球购物
ECCO俄罗斯官网:北欧丹麦鞋履及皮具品牌
2020/06/26 全球购物
医学护理毕业生自荐信
2013/11/07 职场文书
医学院校毕业生自荐信范文
2014/01/01 职场文书
给同事的道歉信
2014/01/11 职场文书
群众路线党员个人剖析材料
2014/10/08 职场文书
2014年会计个人工作总结
2014/11/24 职场文书
Python与C++中梯度方向直方图的实现
2022/03/17 Python
《原神》新角色演示“神里绫人:林隐泓洄” 宠妹狂魔
2022/04/03 其他游戏