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 相关文章推荐
关于 文本框默认值 的操作js代码
Jan 12 Javascript
JQuery给元素添加/删除节点比如select
Apr 02 Javascript
JS的事件绑定深入认识
Jun 26 Javascript
jQuery实现DIV层淡入淡出拖动特效的方法
Feb 13 Javascript
使用PBFunc在Powerbuilder中支付宝当面付款功能
Oct 01 Javascript
jQuery实现弹窗居中效果类似alert()
Feb 27 Javascript
Jquery中attr与prop的区别详解
May 27 jQuery
react-native 完整实现登录功能的示例代码
Sep 11 Javascript
详解如何使用koa实现socket.io官网的例子
Nov 04 Javascript
vue下axios拦截器token刷新机制的实例代码
Jan 17 Javascript
javaScript 实现重复输出给定的字符串的常用方法小结
Feb 20 Javascript
vue中的v-model原理,与组件自定义v-model详解
Aug 04 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中开发XML应用程序之基础篇 添加节点 删除节点 查询节点 查询节
2010/07/09 PHP
写出高质量的PHP程序
2012/02/04 PHP
使用PHP生成图片的缩略图的方法
2015/08/18 PHP
PHP实现图片不变型裁剪及图片按比例裁剪的方法
2016/01/14 PHP
PHP将二维数组某一个字段相同的数组合并起来的方法
2016/02/26 PHP
确保Laravel网站不会被嵌入到其他站点中的方法
2019/10/18 PHP
一份老外写的XMLHttpRequest代码多浏览器支持兼容性
2007/01/11 Javascript
Tab页界面,用jQuery及Ajax技术实现
2009/09/21 Javascript
Ext对基本类型的扩展 ext,extjs,format
2010/12/25 Javascript
js三种排序算法分享
2012/08/16 Javascript
jQuery ajax serialize()方法的使用以及常见问题解决
2013/01/27 Javascript
javascript中函数作为参数调用的方法
2015/02/09 Javascript
jquery+css实现动感的图片切换效果
2015/11/25 Javascript
使用jQuery制作基础的Web图片轮播效果
2016/04/22 Javascript
JS简单测试循环运行时间的方法
2016/09/04 Javascript
浅谈layer的iframe弹窗给里面的标签赋值的问题
2016/11/10 Javascript
html中鼠标滚轮事件onmousewheel的处理方法
2016/11/11 Javascript
JS小数转换为整数的方法分析
2017/01/07 Javascript
Taro集成Redux快速上手的方法示例
2018/06/21 Javascript
Vue数据驱动表单渲染,轻松搞定form表单
2019/07/19 Javascript
Vue使用JSEncrypt实现rsa加密及挂载方法
2020/02/07 Javascript
Vue+elementUI实现多图片上传与回显功能(含回显后继续上传或删除)
2020/03/23 Javascript
Vue实现图书管理小案例
2020/12/03 Vue.js
[10:54]Team Spirit vs Navi
2018/06/07 DOTA
Python编程修改MP3文件名称的方法
2017/04/19 Python
Python语言实现将图片转化为html页面
2017/12/06 Python
Python wxPython库消息对话框MessageDialog用法示例
2018/09/03 Python
Python中*args和**kwargs的区别详解
2019/09/17 Python
如何将 awk 脚本移植到 Python
2019/12/09 Python
Python3 获取文件属性的方式(时间、大小等)
2020/03/12 Python
python 日志模块 日志等级设置失效的解决方案
2020/05/26 Python
解决python和pycharm安装gmpy2 出现ERROR的问题
2020/08/28 Python
基于tensorflow __init__、build 和call的使用小结
2021/02/26 Python
2014应届本科生自我评价
2014/09/13 职场文书
2015年高中生国庆节演讲稿
2015/07/30 职场文书
使用Python脚本对GiteePages进行一键部署的使用说明
2021/05/27 Python