小编这次要给大家分享的是解决Javascript异步执行不按顺序问题,文章内容丰富,感兴趣的小伙伴可以来了解一下,希望大家阅读完这篇文章之后能够有所收获。
案例分析:
比如执行懒加载时候,onscroll事件触发多次事件时候会调用多次ajax回调事件,由于每个事件返回先后次序并不能保证和触发前一致,所以在数据响应返回后所添加的数据顺序就很在推到数组上顺序不一致。
例子1:
var res=[]; 函数响应(数据){ res.push(数据); }//ajax(. .)是某个库中提供的某个ajax函数 ajax (“http://some.url.1"、响应); ajax (“http://some.url.2"、响应);
这里的并发“进程”是这两个用来处理ajax响应的响应()调用。它们可能以任意顺序运行。
我们假定期望的行为是res[0]中放调用“http://some.url.1"的结果,res[1]中放调用“http://some.url.2"的结果。有时候可能是这样,但有时候却恰好相反,这要视哪个调用先完成而定。
这种不确定性很有可能就是一个竞态条件错误。
解决办法
var res=[]; 函数响应(数据){ 如果(数据)。url==癶ttp://some.url.1") { res[0]=数据; } else if(数据。url==癶ttp://some.url.2") { res[1]=数据; } }//ajax(. .)是某个库中提供的某个ajax函数 ajax (“http://some.url.1"、响应); ajax (“http://some.url.2"、响应);
不管哪一个ajax响应先返回,我们都要通过查看数据。url(当然,假定从服务器总会返回一个!)判断应该把响应数据放在res数组中的什么位置上r[0]总是包含“http://some.url.1"的结果,res[1]总是包含“http://some.url.2"的结果。通过简单的协调,就避免了竞态条件引起的不确定性。
例子2:
var a、b; 函数foo (x) {=x * 2; 巴兹(); } 功能栏(y) { b=y * 2; 巴兹(); } 函数巴兹(){ 控制台。日志(a + b); }//ajax(. .)是某个库中的某个ajax函数 ajax (“http://some.url.1" foo); ajax (“http://some.url.2"、酒吧);
在这个例子中,无论foo()和bar()哪一个先被触发,总会使巴兹()过早运行(或者b仍处于未定义状态);但对巴兹()的第二次调用就没有问题,因为这时候a和b都已经可用了。
要解决这个问题有多种方法。这里给出了一种简单方法:
var a、b; 函数foo (x) {=x * 2; 如果一个,,b) { 巴兹(); } } 功能栏(y) { b=y * 2; 如果一个,,b) { 巴兹(); } } 函数巴兹(){ 控制台。日志(a + b); }//ajax(. .)是某个库中的某个ajax函数 ajax (“http://some.url.1" foo); ajax (“http://some.url.2"、酒吧);
包裹巴兹()调用的条件判断如果(一个,,b)传统上称为门(门),我们虽然不能确定a和b到达的顺序,但是会等到它们两个都准备好再进一步打开门(调用巴兹()).
看完这篇关于解决Javascript异步执行不按顺序问题的文章,如果觉得文章内容写得不错的话,可以把它分享出去给更多人看到。