JavaScript 異步調(diào)用框架 (Part 3 - 代碼實(shí)現(xiàn))
更新時間:2009年08月04日 00:04:34 作者:
在上一篇文章里,我們說到了要實(shí)現(xiàn)一個Async.Operation類,通過addCallback方法傳遞回調(diào)函數(shù),并且通過yield方法返回回調(diào)結(jié)果?,F(xiàn)在我們就來實(shí)現(xiàn)這個類吧。
類結(jié)構(gòu)
首先我們來搭一個架子,把需要用到的似有變量都列出來。我們需要一個數(shù)組,來保存回調(diào)函數(shù)列表;需要一個標(biāo)志位,來表示異步操作是否已完成;還可以學(xué)IAsyncResult,加一個state,允許異步操作的實(shí)現(xiàn)者對外暴露自定義的執(zhí)行狀態(tài);最后加一個變量保存異步操作結(jié)果。
Async = {
Operation: {
var callbackQueue = [];
this.result = undefined;
this.state = "waiting";
this.completed = false;
}
}
addCallback方法
接下來,我們要實(shí)現(xiàn)addCallback方法,它的工作職責(zé)很簡單,就是把回調(diào)函數(shù)放到callbackQueue中。此外,如果此時completed為true,說明異步操作已經(jīng)yield過了,則立即調(diào)用此回調(diào)。
this.yield = function(callback) {
callbackQueue.push(callback);
if (this.completed) {
this.yield(this.result);
}
return this;
}
我們假設(shè)yield方法會把callbackQueue中的回調(diào)函數(shù)逐個取出來然后調(diào)用,因此如果compeleted為true,則使用已有的result再調(diào)用一次yield就可以了,這樣yield自然會調(diào)用這次添加到callbackQueue的回調(diào)函數(shù)。
至于最后的return this;,只是為了方便jQuery風(fēng)格的鏈?zhǔn)綄懛?,可以通過點(diǎn)號分隔連續(xù)添加多個回調(diào)函數(shù):
asyncOperation(argument)
.addCallback(firstCallback)
.addCallback(secondCallback);
yield方法
最后,我們要實(shí)現(xiàn)yield方法。它需要將callbackQueue中的回調(diào)函數(shù)逐個取出來,然后都調(diào)用一遍,并且保證這個操作是異步吧。
this.yield = function(result) {
var self = this;
setTimeout(function() {
self.result = result;
self.state = "completed";
self.completed = true;
while (callbackQueue.length > 0) {
var callback = callbackQueue.shift();
callback(self.result);
}
}, 1);
return this;
}
通過使用setTimeout,我們確保了yield的實(shí)際操作是異步進(jìn)行的。然后我們把用戶傳入yield的結(jié)果及相關(guān)狀態(tài)更新到對象屬性之上,最后遍歷callbackQueue調(diào)用所有的回調(diào)函數(shù)。
小結(jié)
這樣我們就做好了一個簡單的JavaScript異步調(diào)用框架,完整的代碼可以看這里:異步調(diào)用框架Async.Operation。
這個框架能夠很好的解決調(diào)用棧中出現(xiàn)同步異步操作并存的情況,假設(shè)所有函數(shù)都返回Async.Operation,框架的使用者可以使用一種統(tǒng)一的模式來編寫代碼,處理函數(shù)返回,而無需關(guān)心這個函數(shù)實(shí)際上是同步返回了還是異步返回了。
對于串行調(diào)用多個異步函數(shù)的情況,我們現(xiàn)在可以用嵌套addCallback的方式來書寫,但隨著嵌套層數(shù)的增多,代碼會變得越來越不美觀:
firstAsyncOperation().addCallback(function() {
secondAsyncOperation().addCallback(function() {
thirdAsyncOperation().addCallback(function() {
finalSyncOperation();
});
});
});
我們能否把嵌套形式改為jQuery風(fēng)格的鏈?zhǔn)綄懛兀窟@是我們接下來要思考的問題,如果你不希望錯過相關(guān)討論的話
首先我們來搭一個架子,把需要用到的似有變量都列出來。我們需要一個數(shù)組,來保存回調(diào)函數(shù)列表;需要一個標(biāo)志位,來表示異步操作是否已完成;還可以學(xué)IAsyncResult,加一個state,允許異步操作的實(shí)現(xiàn)者對外暴露自定義的執(zhí)行狀態(tài);最后加一個變量保存異步操作結(jié)果。
復(fù)制代碼 代碼如下:
Async = {
Operation: {
var callbackQueue = [];
this.result = undefined;
this.state = "waiting";
this.completed = false;
}
}
addCallback方法
接下來,我們要實(shí)現(xiàn)addCallback方法,它的工作職責(zé)很簡單,就是把回調(diào)函數(shù)放到callbackQueue中。此外,如果此時completed為true,說明異步操作已經(jīng)yield過了,則立即調(diào)用此回調(diào)。
復(fù)制代碼 代碼如下:
this.yield = function(callback) {
callbackQueue.push(callback);
if (this.completed) {
this.yield(this.result);
}
return this;
}
我們假設(shè)yield方法會把callbackQueue中的回調(diào)函數(shù)逐個取出來然后調(diào)用,因此如果compeleted為true,則使用已有的result再調(diào)用一次yield就可以了,這樣yield自然會調(diào)用這次添加到callbackQueue的回調(diào)函數(shù)。
至于最后的return this;,只是為了方便jQuery風(fēng)格的鏈?zhǔn)綄懛?,可以通過點(diǎn)號分隔連續(xù)添加多個回調(diào)函數(shù):
復(fù)制代碼 代碼如下:
asyncOperation(argument)
.addCallback(firstCallback)
.addCallback(secondCallback);
yield方法
最后,我們要實(shí)現(xiàn)yield方法。它需要將callbackQueue中的回調(diào)函數(shù)逐個取出來,然后都調(diào)用一遍,并且保證這個操作是異步吧。
復(fù)制代碼 代碼如下:
this.yield = function(result) {
var self = this;
setTimeout(function() {
self.result = result;
self.state = "completed";
self.completed = true;
while (callbackQueue.length > 0) {
var callback = callbackQueue.shift();
callback(self.result);
}
}, 1);
return this;
}
通過使用setTimeout,我們確保了yield的實(shí)際操作是異步進(jìn)行的。然后我們把用戶傳入yield的結(jié)果及相關(guān)狀態(tài)更新到對象屬性之上,最后遍歷callbackQueue調(diào)用所有的回調(diào)函數(shù)。
小結(jié)
這樣我們就做好了一個簡單的JavaScript異步調(diào)用框架,完整的代碼可以看這里:異步調(diào)用框架Async.Operation。
這個框架能夠很好的解決調(diào)用棧中出現(xiàn)同步異步操作并存的情況,假設(shè)所有函數(shù)都返回Async.Operation,框架的使用者可以使用一種統(tǒng)一的模式來編寫代碼,處理函數(shù)返回,而無需關(guān)心這個函數(shù)實(shí)際上是同步返回了還是異步返回了。
對于串行調(diào)用多個異步函數(shù)的情況,我們現(xiàn)在可以用嵌套addCallback的方式來書寫,但隨著嵌套層數(shù)的增多,代碼會變得越來越不美觀:
復(fù)制代碼 代碼如下:
firstAsyncOperation().addCallback(function() {
secondAsyncOperation().addCallback(function() {
thirdAsyncOperation().addCallback(function() {
finalSyncOperation();
});
});
});
我們能否把嵌套形式改為jQuery風(fēng)格的鏈?zhǔn)綄懛兀窟@是我們接下來要思考的問題,如果你不希望錯過相關(guān)討論的話
您可能感興趣的文章:
- JavaScript 異步調(diào)用框架 (Part 1 - 問題 & 場景)
- JavaScript 異步調(diào)用框架 (Part 2 - 用例設(shè)計(jì))
- JavaScript 異步調(diào)用框架 (Part 4 - 鏈?zhǔn)秸{(diào)用)
- JavaScript 異步調(diào)用框架 (Part 5 - 鏈?zhǔn)綄?shí)現(xiàn))
- javascript 支持鏈?zhǔn)秸{(diào)用的異步調(diào)用框架Async.Operation
- JavaScript 異步調(diào)用框架 (Part 6 - 實(shí)例 & 模式)
- JavaScript異步調(diào)用定時方法并停止該方法實(shí)現(xiàn)代碼
- Java多線程實(shí)現(xiàn)異步調(diào)用的方法
相關(guān)文章
解決Layui選擇全部,換頁checkbox復(fù)選框重新勾選的問題方法
今天小編就為大家分享一篇解決Layui選擇全部,換頁checkbox復(fù)選框重新勾選的問題方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08table對象中的insertRow與deleteRow使用示例
本文為大家介紹下table對象insertRow deleteRow的使用示例,適合新手朋友們2014-01-01javascript實(shí)現(xiàn)當(dāng)前頁導(dǎo)航激活的方法
這篇文章主要介紹了javascript實(shí)現(xiàn)當(dāng)前頁導(dǎo)航激活的方法,涉及javascript操作css的技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-02-02Locate a File Using a File Open Dialog Box
Locate a File Using a File Open Dialog Box...2007-06-06JavaScript面試必備之垃圾回收機(jī)制和內(nèi)存泄漏詳解
垃圾回收機(jī)制和內(nèi)存泄漏是JavaScript面試時常常問到的問題,這篇文章就為大家詳細(xì)整理了他們的相關(guān)知識,感興趣的小伙伴可以跟隨小編一起了解一下2023-05-05JavaScript表單驗(yàn)證實(shí)現(xiàn)過程詳解
表單校驗(yàn)是注冊環(huán)節(jié)中必不可少的操作,表單校驗(yàn)通過一定的規(guī)則來確保用戶提交數(shù)據(jù)的有效性,下面這篇文章主要給大家介紹了關(guān)于el-form表單驗(yàn)證的一些實(shí)用方法,需要的朋友可以參考下2023-01-01