时间:2021-05-26
案例分析:
比如执行懒加载时候,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 都已经可用了。
要解决这个问题有多种方法。这里给出了一种简单方法:
包裹baz()调用的条件判断if (a && b)传统上称为门(gate),我们虽然不能确定a和b 到达的顺序,但是会等到它们两个都准备好再进一步打开门(调用 baz())。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
一.前言我们经常会遇到这样的麻烦事,多个函数按顺序执行,返回结果却不是我们预期的顺序,原因一般是由于异步操作引起的,所以呢,我们需要一种解决方案来处理这种问题,
JavaScript的Promise.all()Promise是JavaScript异步编程的一种解决方案,在ES6中引入。通过Promise.all()可以实
前言Promise是JavaScript异步操作解决方案,最近看到项目里不少人用了Promise的库类,比如bluebird、q、jQuery.Deffered
AndroidListView异步加载图片错位、重复、闪烁分析以及解决方案,具体问题分析以及解决方案请看下文。我们在使用ListView异步加载图片的时候,在快
ES6新引入了Generator函数,可以通过yield关键字,把函数的执行流挂起,为改变执行流程提供了可能,从而为异步编程提供解决方案。基本用法Generat