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 05 Javascript
JS无限树状列表实现代码
Jan 11 Javascript
基于JQuery实现鼠标点击文本框显示隐藏提示文本
Feb 23 Javascript
Jquery和JS用外部变量获取Ajax返回的参数值的方法实例(超简单)
Jun 17 Javascript
jQuery实现的产品自动360度旋转展示特效源码分享
Aug 21 Javascript
vue多级多选菜单组件开发
Sep 08 Javascript
基于Vue2的移动端开发环境搭建详解
Nov 03 Javascript
Vue父组件调用子组件事件方法
Feb 23 Javascript
详解Vue CLI3配置解析之css.extract
Sep 14 Javascript
vue项目中实现图片预览的公用组件功能
Oct 26 Javascript
基于vue2.0实现仿百度前端分页效果附实现代码
Oct 30 Javascript
在Vue中使用icon 字体图标的方法
Jun 14 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获取某个目录大小的代码
2008/09/10 PHP
简单的方法让你的后台登录更加安全(php中加session验证)
2012/08/22 PHP
php生成验证码函数
2015/10/20 PHP
PHP检查端口是否可以被绑定的方法示例
2018/08/09 PHP
用javascript实现点击链接弹出"图片另存为"而不是直接打开
2007/08/15 Javascript
JQuery 学习笔记 选择器之二
2009/07/23 Javascript
php上传图片并给图片打上透明水印的代码
2010/06/07 Javascript
jquery如何获取复选框的值
2013/12/12 Javascript
jquery缓动swing liner控制动画过程不同时刻的速度
2014/05/29 Javascript
node.js中的fs.readdir方法使用说明
2014/12/17 Javascript
jquery动态改变div宽度和高度
2015/02/09 Javascript
JavaScript中的ajax功能的概念和示例详解
2016/10/17 Javascript
js实现横向拖拽导航条功能
2017/02/17 Javascript
极简主义法编写JavaScript类
2017/11/02 Javascript
解决vue 中 echart 在子组件中只显示一次的问题
2018/08/07 Javascript
基于Bootstrap下拉框插件bootstrap-select使用方法详解
2018/08/07 Javascript
vue form 表单提交后刷新页面的方法
2018/09/04 Javascript
Vue实现剪切板图片压缩功能
2020/02/04 Javascript
vue实现移动端触屏拖拽功能
2020/08/21 Javascript
[01:45:05]VGJ.T vs Newbee Supermajor 败者组 BO3 第二场 6.6
2018/06/07 DOTA
Python3基础之基本数据类型概述
2014/08/13 Python
python实现对文件中图片生成带标签的txt文件方法
2018/04/27 Python
python 判断三个数字中的最大值实例代码
2019/07/24 Python
python Matplotlib底图中鼠标滑过显示隐藏内容的实例代码
2019/07/31 Python
pandas中遍历dataframe的每一个元素的实现
2019/10/23 Python
Python数据持久化存储实现方法分析
2019/12/21 Python
Python参数传递机制传值和传引用原理详解
2020/05/22 Python
Python爬虫之App爬虫视频下载的实现
2020/12/08 Python
世界领先的26岁以下学生和青少年旅行预订网站:StudentUniverse
2018/07/01 全球购物
什么是Remote Module
2016/06/10 面试题
药学专业个人自我评价
2013/11/11 职场文书
后勤人员岗位职责
2013/12/17 职场文书
统计系教授推荐信
2014/02/28 职场文书
食品工程专业求职信
2014/06/15 职场文书
2016年中秋节晚会领导致辞
2015/11/26 职场文书
如何使用注解方式实现 Redis 分布式锁
2022/07/23 Redis