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进行拖拽
Jul 20 Javascript
javascript 动态设置已知select的option的value值的代码
Dec 16 Javascript
你必须知道的JavaScript 中字符串连接的性能的一些问题
May 07 Javascript
jQuery的attr与prop使用介绍
Oct 10 Javascript
JS实现匀速运动的代码实例
Nov 29 Javascript
jQuery中:last选择器用法实例
Dec 30 Javascript
JS实现仿微博可关闭弹出层效果
Sep 21 Javascript
JS组件Bootstrap导航条使用方法详解
Apr 29 Javascript
jQuery实现的简单分页示例
Jun 01 Javascript
解决拦截器对ajax请求的拦截实例详解
Dec 21 Javascript
微信小程序中顶部导航栏的实现代码
Mar 30 Javascript
使用nvm管理不同版本的node与npm的方法
Oct 31 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
如何将数据从文本导入到mysql
2006/10/09 PHP
php 生成WML页面方法详解
2009/08/09 PHP
php实现文件管理与基础功能操作
2017/03/21 PHP
根据分辩率调用不同的CSS.
2007/01/08 Javascript
15款jQuery分布引导插件分享
2015/02/04 Javascript
js实现鼠标点击左上角滑动菜单效果代码
2015/09/06 Javascript
全面解析Bootstrap表单使用方法(表单样式)
2015/11/24 Javascript
jQuery插件formValidator实现表单验证
2016/05/23 Javascript
Ext JS框架程序中阻止键盘触发回退或者刷新页面的代码分享
2016/06/07 Javascript
JS调用打印机功能简单示例
2016/11/28 Javascript
jquery dataview数据视图插件使用方法
2016/12/23 Javascript
关于使用js算总价的问题
2017/06/23 Javascript
jQuery实现点击自身以外区域关闭弹出层功能完整示例【改进版】
2018/07/31 jQuery
关于微信小程序登录的那些事
2019/01/08 Javascript
详解在网页上通过JS实现文本的语音朗读
2019/03/28 Javascript
全面分析JavaScript 继承
2019/05/30 Javascript
简单实现python爬虫功能
2015/12/31 Python
python正则表达式面试题解答
2020/04/28 Python
Python3.5.3下配置opencv3.2.0的操作方法
2018/04/02 Python
详解Python的三种可变参数
2019/05/08 Python
python儿童学游戏编程知识点总结
2019/06/03 Python
pytorch中torch.max和Tensor.view函数用法详解
2020/01/03 Python
tensorflow 实现自定义layer并添加到计算图中
2020/02/04 Python
Python基于模块Paramiko实现SSHv2协议
2020/04/28 Python
python中操作文件的模块的方法总结
2021/02/04 Python
html5记忆翻牌游戏实现思路及代码
2013/07/25 HTML / CSS
详解canvas多边形(蜘蛛图)的画法示例
2018/01/29 HTML / CSS
选购国际女性时装设计师品牌:IFCHIC(支持中文)
2018/04/12 全球购物
上课随便讲话检讨书
2014/09/12 职场文书
2015元旦晚会主持人开场白+结束语
2014/12/14 职场文书
董事长助理工作总结2015
2015/07/23 职场文书
2015年语言文字工作总结
2015/07/23 职场文书
2016教师校本培训心得体会
2016/01/08 职场文书
2019年个人工作总结范文(3篇)
2019/08/27 职场文书
浅析Django接口版本控制
2021/06/26 Python
python中 Flask Web 表单的使用方法
2022/05/20 Python