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中expression的用法整理
May 13 Javascript
js中的caller和callee属性介绍和例子
Jun 07 Javascript
原生js和jquery实现图片轮播特效
Apr 23 Javascript
JavaScript中字面量与函数的基本使用知识
Oct 20 Javascript
轻松实现javascript数据双向绑定
Nov 11 Javascript
JavaScript-定时器0~9抽奖系统详解(代码)
Aug 16 Javascript
vue中如何实现pdf文件预览的方法
Jul 12 Javascript
JS函数参数的传递与同名参数实例分析
Mar 16 Javascript
vue实现商品列表的添加删除实例讲解
May 14 Javascript
javascript读取本地文件和目录方法详解
Aug 06 Javascript
JavaScript Image对象实现原理实例解析
Aug 26 Javascript
简单聊聊TypeScript只读修饰符
Apr 06 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
菜鸟修复电子管记
2021/03/02 无线电
ThinkPHP CURD方法之where方法详解
2014/06/18 PHP
php如何连接sql server
2015/10/16 PHP
php-msf源码详解
2017/12/25 PHP
Yii框架where查询用法实例分析
2019/10/22 PHP
用js实现层随着内容大小动态渐变改变 推荐
2009/12/19 Javascript
JavaScript 常用函数
2009/12/30 Javascript
JQuery魔力之$("tagName")与selector
2012/03/05 Javascript
GRID拖拽行的实例代码
2013/07/18 Javascript
js中this的用法实例分析
2015/01/10 Javascript
jQuery代码实现发展历程时间轴特效
2015/07/30 Javascript
js 获取范围内的随机数实例代码
2016/08/02 Javascript
JS实现物体带缓冲的间歇运动效果示例
2016/12/22 Javascript
jQuery插件HighCharts实现的2D对数饼图效果示例【附demo源码下载】
2017/03/09 Javascript
JQuery判断正整数整理小结
2017/08/21 jQuery
nodejs中安装ghost出错的原因及解决方法
2017/10/23 NodeJs
微信小程序踩坑记录之解决tabBar.list[3].selectedIconPath大小超过40kb
2018/07/04 Javascript
微信小程序实现多选框全选与取消全选功能示例
2019/05/14 Javascript
jQuery 图片查看器插件 Viewer.js用法简单示例
2020/04/04 jQuery
python实现斐波那契递归函数的方法
2014/09/08 Python
Python中用于计算对数的log()方法
2015/05/15 Python
python实现TF-IDF算法解析
2018/01/02 Python
Python requests库用法实例详解
2018/08/14 Python
使用Python实现微信提醒备忘录功能
2018/12/04 Python
一个可以套路别人的python小程序实例代码
2019/04/09 Python
python 成功引入包但无法正常调用的解决
2020/03/09 Python
python使用QQ邮箱实现自动发送邮件
2020/06/22 Python
用html5实现语音搜索框的方法
2014/03/18 HTML / CSS
印度尼西亚综合购物网站:Lazada印尼
2016/09/07 全球购物
SHEIN美国:购买时髦的女性服装
2020/12/02 全球购物
高分子材料个人求职信范文
2013/09/25 职场文书
女大学生个人求职信
2013/12/09 职场文书
个人三严三实对照检查材料
2014/09/25 职场文书
2016年春季开学典礼新闻稿
2015/11/25 职场文书
2016大学生优秀志愿者事迹材料
2016/02/25 职场文书
详细聊一聊mysql的树形结构存储以及查询
2022/04/05 MySQL