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 学习笔记(十四) 正则表达式
Jan 22 Javascript
YUI Compressor压缩JavaScript原理及微优化
Jan 07 Javascript
使用jQuery清空file文件域的解决方案
Apr 12 Javascript
js单例模式的两种方案
Oct 22 Javascript
js简单实现删除记录时的提示效果
Dec 05 Javascript
jquery原创弹出层折叠效果点击折叠弹出一个层
Mar 12 Javascript
EasyUI实现第二层弹出框的方法
Mar 01 Javascript
使用AOP改善javascript代码
May 01 Javascript
JavaScript中iframe实现局部刷新的几种方法汇总
Jan 06 Javascript
关于Node.js的events.EventEmitter用法介绍
Apr 01 Javascript
Vue.js项目实战之多语种网站的功能实现(租车)
Aug 07 Javascript
微信小程序实现日历小功能
Nov 18 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&mysql(四)
2006/10/09 PHP
把1316这个数表示成两个数的和,其中一个为13的倍数,另一个是11的倍数,求这两个数。
2011/06/24 PHP
PHP __autoload()方法真的影响性能吗?
2012/03/30 PHP
PHP与MongoDB简介|安全|M+PHP应用实例详解
2013/06/17 PHP
php定义参数数量可变的函数用法实例
2015/03/16 PHP
Yii2中cookie用法示例分析
2016/07/18 PHP
php集成动态口令认证
2016/07/21 PHP
php实现当前页面点击下载文件的简单方法
2016/09/22 PHP
JavaScript正则表达式匹配 div  style标签
2016/03/15 Javascript
浅谈JS之iframe中的窗口
2016/09/13 Javascript
原生JS和jQuery操作DOM对比总结
2017/01/19 Javascript
微信小程序 页面跳转传值实现代码
2017/07/27 Javascript
js 图片转base64的方式(两种)
2018/04/24 Javascript
手挽手带你学React之React-router4.x的使用
2019/02/14 Javascript
JavaScript 如何计算文本的行数的实现
2020/09/14 Javascript
关于pip的安装,更新,卸载模块以及使用方法(详解)
2017/05/19 Python
python 上下文管理器使用方法小结
2017/10/10 Python
Python函数基础实例详解【函数嵌套,命名空间,函数对象,闭包函数等】
2019/03/30 Python
python 读取数据库并绘图的实例
2019/12/03 Python
pytorch:实现简单的GAN示例(MNIST数据集)
2020/01/10 Python
tensorflow中tf.reduce_mean函数的使用
2020/04/19 Python
pandas to_excel 添加颜色操作
2020/07/14 Python
python 常用日期处理-- datetime 模块的使用
2020/09/02 Python
Python中使用Selenium环境安装的方法步骤
2021/02/22 Python
香港迪士尼乐园酒店预订:Hong Kong Disneyland Hotels
2017/05/02 全球购物
越南电子产品购物网站:FPT Shop
2017/12/02 全球购物
佳能加拿大网上商店:Canon eStore Canada
2018/04/04 全球购物
台湾旅游网站:灿星旅游
2018/10/11 全球购物
Bluebella法国官网:英国性感内衣品牌
2019/05/03 全球购物
俄罗斯披萨、寿司和面食送货到家服务:2 Берега
2019/12/15 全球购物
在校生汽车维修实习自我鉴定
2013/09/19 职场文书
《月亮湾》教学反思
2014/04/14 职场文书
专业见习报告范文
2014/11/03 职场文书
体育教师教学随笔
2015/08/15 职场文书
2016北大自主招生自荐信模板
2016/01/28 职场文书
Python 游戏大作炫酷机甲闯关游戏爆肝数千行代码实现案例进阶
2021/10/16 Python