Javascript異步執(zhí)行不按順序解決方案
案例分析:
比如執(zhí)行懶加載時候,onscroll 事件觸發(fā)多次事件時候會調(diào)用多次 ajax 回調(diào)事件,由于每個事件返回先后次序并不能保證和觸發(fā)前一致,所以在數(shù)據(jù)響應(yīng)返回后所添加的數(shù)據(jù)順序就很在 push 到數(shù)組上順序不一致。
例子1:
var res = [];
function response(data) {
res.push( data );
}
// ajax(..)是某個庫中提供的某個Ajax函數(shù)
ajax( "http://some.url.1", response );
ajax( "http://some.url.2", response );
這里的并發(fā)“進程”是這兩個用來處理 Ajax 響應(yīng)的 response() 調(diào)用。它們可能以任意順 序運行。
我們假定期望的行為是 res[0] 中放調(diào)用 "http://some.url.1" 的結(jié)果,res[1] 中放調(diào)用 "http://some.url.2" 的結(jié)果。有時候可能是這樣,但有時候卻恰好相反,這要視哪個調(diào) 用先完成而定。
這種不確定性很有可能就是一個競態(tài)條件 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函數(shù)
ajax( "http://some.url.1", response );
ajax( "http://some.url.2", response );
不管哪一個 Ajax 響應(yīng)先返回,我們都要通過查看 data.url(當(dāng)然,假定從服務(wù)器總會返 回一個!)判斷應(yīng)該把響應(yīng)數(shù)據(jù)放在 res 數(shù)組中的什么位置上。res[0] 總是包含 "http:// some.url.1" 的結(jié)果,res[1] 總是包含 "http://some.url.2" 的結(jié)果。通過簡單的協(xié)調(diào),就 避免了競態(tài)條件引起的不確定性。
例子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函數(shù)
ajax( "http://some.url.1", foo );
ajax( "http://some.url.2", bar );
在這個例子中,無論 foo() 和 bar() 哪一個先被觸發(fā),總會使 baz() 過早運行(a 或者 b 仍處 于未定義狀態(tài));但對 baz() 的第二次調(diào)用就沒有問題,因為這時候 a 和 b 都已經(jīng)可用了。
要解決這個問題有多種方法。這里給出了一種簡單方法:
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函數(shù)
ajax( "http://some.url.1", foo );
ajax( "http://some.url.2", bar );
包裹baz()調(diào)用的條件判斷if (a && b)傳統(tǒng)上稱為門(gate),我們雖然不能確定a和b 到達的順序,但是會等到它們兩個都準備好再進一步打開門(調(diào)用 baz())。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
動態(tài)規(guī)劃之使用備忘錄來改進Javascript函數(shù)
這篇文章主要介紹了動態(tài)規(guī)劃之使用備忘錄來改進Javascript函數(shù),動態(tài)規(guī)劃它既是一種數(shù)學(xué)優(yōu)化方法,也是一種計算機編程方法,下文相關(guān)資料介紹需要的小伙伴可以參考一下2022-04-04
純JavaScript 實現(xiàn)flappy bird小游戲?qū)嵗a
這篇文章主要介紹了純JavaScript 實現(xiàn)flappy bird小游戲?qū)嵗a,b本文分七大步驟給大家介紹,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-09-09
javascript結(jié)合canvas實現(xiàn)圖片旋轉(zhuǎn)效果
圖片的旋轉(zhuǎn)可以說是一種效果,但是逐漸旋轉(zhuǎn)已經(jīng)不單單是屬于視覺效果那個范疇,其更具有使用性,功能性。照片有時候是需要橫過來的拍的,當(dāng)我們預(yù)覽或共享到web上時需要進行旋轉(zhuǎn)。這個操作在以往可能更多的是交給軟件去完成,然后再將旋轉(zhuǎn)到正常角度的圖片發(fā)布到web上。2015-05-05

