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 动态酷效果实现总结
Dec 27 Javascript
javascript两种function的定义介绍及区别说明
May 02 Javascript
遍历DOM对象内的元素属性示例代码
Feb 08 Javascript
jQuery内置的AJAX功能和JSON的使用实例
Jul 27 Javascript
javascript的push使用指南
Dec 05 Javascript
jQuery中ajax的load()方法用法实例
Dec 26 Javascript
实例讲解jQuery EasyUI tree中state属性慎用
Apr 01 Javascript
用原生JS对AJAX做简单封装的实例代码
Jul 13 Javascript
详解javascript常用工具类的封装
Jan 30 Javascript
Vue 菜单栏点击切换单个class(高亮)的方法
Aug 22 Javascript
vue二级菜单导航点击选中事件的方法
Sep 12 Javascript
微信小程序学习笔记之跳转页面、传递参数获得数据操作图文详解
Mar 28 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数组函数序列之krsort()- 对数组的元素键名进行降序排序,保持索引关系
2011/11/02 PHP
基于PHP文件操作的详解
2013/06/05 PHP
最常用的8款PHP调试工具
2014/07/06 PHP
PHP安装threads多线程扩展基础教程
2015/11/17 PHP
PHP htmlspecialchars()函数用法与实例讲解
2019/03/08 PHP
php文件操作之文件写入字符串、数组的方法分析
2019/04/15 PHP
thinkphp框架无限级栏目的排序功能实现方法示例
2020/03/29 PHP
js获取时间(本周、本季度、本月..)
2013/11/22 Javascript
JS delegate与live浅析
2013/12/21 Javascript
JavaScript前端图片加载管理器imagepool使用详解
2014/12/29 Javascript
jQuery调用ajax请求的常见方法汇总
2015/03/24 Javascript
JavaScript截取、切割字符串的技巧
2016/01/07 Javascript
动态的9*9乘法表效果的实现代码
2016/05/16 Javascript
JavaScript的for循环中嵌套一个点击事件的问题解决
2017/03/03 Javascript
详解webpack 多页面/入口支持&公共组件单独打包
2017/06/29 Javascript
Canvas放置反弹效果随机图形(实例)
2017/08/17 Javascript
vue2.0 如何把子组件的数据传给父组件(推荐)
2018/01/15 Javascript
JS实现面向对象继承的5种方式分析
2018/07/21 Javascript
Vue入门之数量加减运算操作示例
2018/12/11 Javascript
在微信小程序中渲染HTML内容3种解决方案及分析与问题解决
2020/01/12 Javascript
js原生map实现的方法总结
2020/01/19 Javascript
python动态性强类型用法实例
2015/05/09 Python
python地震数据可视化详解
2019/06/18 Python
用python生成与调用cntk模型代码演示方法
2019/08/26 Python
Pytorch 定义MyDatasets实现多通道分别输入不同数据方式
2020/01/15 Python
Pytest参数化parametrize使用代码实例
2020/02/22 Python
Pytorch生成随机数Tensor的方法汇总
2020/09/09 Python
任课老师推荐信范文
2013/11/24 职场文书
高一地理教学反思
2014/01/18 职场文书
学校安全教育制度
2014/01/31 职场文书
优秀士兵先进事迹
2014/02/06 职场文书
《金钱的魔力》教学反思
2014/02/24 职场文书
合作经营协议书范本
2014/09/16 职场文书
学习心理学心得体会
2016/01/22 职场文书
MySQL中IF()、IFNULL()、NULLIF()、ISNULL()函数的使用详解
2021/06/26 MySQL
关于JavaScript 中 if包含逗号表达式
2021/11/27 Javascript