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的load函数动态加载其它页面的内容的实现代码
Dec 14 Javascript
各情景下元素宽高的获取实现代码
Sep 13 Javascript
javascript重复绑定事件造成的后果说明
Mar 02 Javascript
JS Jquery 遍历,筛选页面元素 自动完成(实现代码)
Jul 08 Javascript
JS脚本defer的作用示例介绍
Jan 02 Javascript
jQuery基本选择器(实例及表单域value的获取方法)
May 20 Javascript
html5 canvas 详细使用教程
Jan 20 Javascript
Bootstrap实现基于carousel.js框架的轮播图效果
May 02 Javascript
Element-ui table中过滤条件变更表格内容的方法
Mar 02 Javascript
监控微信小程序中的慢HTTP请求过程详解
Jul 05 Javascript
使用flow来规范javascript的变量类型
Sep 12 Javascript
jquery轻量级数字动画插件countUp.js使用详解
Oct 17 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
DOTA2 1月28日更新:监管系统降临刀塔世界
2021/01/28 DOTA
PHP4实际应用经验篇(2)
2006/10/09 PHP
PHP实时显示输出
2008/10/02 PHP
PHP 变量的定义方法
2010/01/26 PHP
PHP上传图片进行等比缩放可增加水印功能
2014/01/13 PHP
CentOS下PHP安装Oracle扩展
2015/02/15 PHP
分享php分页的功能模块
2015/06/16 PHP
PHP获取当前时间不准确问题解决方案
2020/08/14 PHP
深入理解JSON数据源格式
2014/01/10 Javascript
JavaScript中字符串分割函数split用法实例
2015/04/07 Javascript
JS实现黑色大气的二级导航菜单效果
2015/09/18 Javascript
AngularJS入门教程之REST和定制服务详解
2016/08/19 Javascript
浅谈js中的引用和复制(传值和传址)
2016/09/18 Javascript
微信小程序 底部导航栏目开发资料
2016/12/05 Javascript
基于JS实现的随机数字抽签实例
2016/12/08 Javascript
详解jQuery中的DOM操作
2016/12/23 Javascript
nodejs搭建本地服务器并访问文件的方法
2017/03/03 NodeJs
ES6新特性六:promise对象实例详解
2017/04/21 Javascript
jQuery实现选中行变色效果(实例讲解)
2017/07/06 jQuery
js实现鼠标拖拽多选功能示例
2017/08/01 Javascript
浅析JS抽象工厂模式
2017/12/14 Javascript
js消除图片小游戏代码
2019/12/11 Javascript
在vue项目实现一个ctrl+f的搜索功能
2020/02/28 Javascript
Python中的条件判断语句基础学习教程
2016/02/07 Python
KMP算法精解及其Python版的代码示例
2016/06/01 Python
python整合ffmpeg实现视频文件的批量转换
2019/05/31 Python
关于Keras模型可视化教程及关键问题的解决
2020/01/24 Python
python相对企业语言优势在哪
2020/06/12 Python
Doyoueven官网:澳大利亚健身服饰和配饰品牌
2019/03/24 全球购物
Myprotein法国官网:欧洲第一运动营养品牌
2019/03/26 全球购物
美国波西米亚风格精品店:South Moon Under
2019/10/26 全球购物
促销活动策划方案
2014/01/12 职场文书
群众路线教育实践活动心得体会
2014/03/07 职场文书
2015年城管个人工作总结范文
2015/04/20 职场文书
教师实习自我鉴定总结
2019/08/20 职场文书
nginx服务器的下载安装与使用详解
2021/08/02 Servers