JavaScript 異步調(diào)用框架 (Part 5 - 鏈?zhǔn)綄崿F(xiàn))
更新時間:2009年08月04日 00:11:43 作者:
在上一篇文章里面,我們?yōu)楫惒秸{(diào)用框架設(shè)計了一種鏈?zhǔn)秸{(diào)用方式,來增強(qiáng)異步調(diào)用隊列的代碼可讀性,現(xiàn)在我們就來編寫實現(xiàn)這部分功能的代碼。
調(diào)用入口
鏈?zhǔn)秸{(diào)用存在Async.go方法和Async.chain方法兩個入口,這兩個入口本質(zhì)上是一致的,只是Async.chain方法在調(diào)用時先不提供初始參數(shù),而Async.go方法在調(diào)用時提供了初始參數(shù)并啟動異步調(diào)用鏈。
Async.chain = function() {
var chain = new Async.Operation({ chain: true });
return chain;
};
Async.go = function(initialArgument) {
return Async.chain().go(initialArgument);
}
在這里我們可以看到,鏈?zhǔn)秸{(diào)用本身也是一個Async.Operation,鏈?zhǔn)秸{(diào)用所需的go方法和next方法都是在Async.Operation上面做的擴(kuò)展,并且這個擴(kuò)展不會很難,這將在下一小節(jié)說明。
擴(kuò)展方法
我們都知道,通過addCallback方法添加的回調(diào)函數(shù)是會被逐一執(zhí)行的,至少同步函數(shù)如此,因此我們可以用Async.Operation的這一特性來維護(hù)異步調(diào)用隊列,前提是我們?yōu)樗由蠈Ξ惒秸{(diào)用進(jìn)行隊列的支持。
對于異步調(diào)用進(jìn)行隊列的支持,我們稍后再來處理,首先我們利用現(xiàn)成的addCallback方法和yield方法擴(kuò)展出go方法和next方法。
this.go = function(initialArgument) {
return this.yield(initialArgument);
}
this.next = function(nextFunction) {
return this.addCallback(nextFunction);
};
實際上,go方法和next方法直接調(diào)用的正是yield方法和addCallback方法。go方法的語義與yield方法一樣,傳遞一個參數(shù)給Async.Operation實例,并且啟動調(diào)用隊列。同時,next方法的語義和addCallback方法,添加一個調(diào)用到隊列的末端。
異步隊列
如何才能讓原本僅支持同步的隊列變得也支持異步?這需要檢測隊列中的每一個調(diào)用的返回,如果返回類型為Async.Operation,我們知道是異步調(diào)用,從而使用特殊的方法等它執(zhí)行完后再執(zhí)行下去。
callbackResult = callback(self.result);
self.result = callbackResult;
if (callbackResult && callbackResult instanceof Async.Operation) {
innerChain = Async.chain();
while (callbackQueue.length > 0) {
innerChain.next(callbackQueue.shift());
}
innerChain.next(function(result) {
self.result = result;
self.state = "completed";
self.completed = true;
return result;
});
callbackResult.addCallback(function(result) {
self.result = result;
innerChain.go(result);
});
}
如果調(diào)用返回了一個Async.Operation實例,我們就利用它自身的addCallback方法幫我們執(zhí)行隊列中余下的調(diào)用。準(zhǔn)確來說,是我們構(gòu)造了一個新的調(diào)用鏈,把隊列余下的調(diào)用都轉(zhuǎn)移到新的調(diào)用鏈上,然后讓當(dāng)前異步調(diào)用在回調(diào)中啟動這個新的調(diào)用鏈。
此外還有一些地方我們需要略作修改,以兼容新的異步調(diào)用隊列的。例如result、state、completed的狀態(tài)變更,在鏈?zhǔn)秸{(diào)用中是有所不同的。
小結(jié)
我們在原有的Async.Operation上略作修改,使得它支持異步調(diào)用隊列,完整的代碼看這里:支持鏈?zhǔn)秸{(diào)用的異步調(diào)用框架Async.Operation。
現(xiàn)在我們已經(jīng)擁有了一個功能強(qiáng)大的Async.Operation,接下來我們就要看看如何將它投入到更多常見的使用模式中去
鏈?zhǔn)秸{(diào)用存在Async.go方法和Async.chain方法兩個入口,這兩個入口本質(zhì)上是一致的,只是Async.chain方法在調(diào)用時先不提供初始參數(shù),而Async.go方法在調(diào)用時提供了初始參數(shù)并啟動異步調(diào)用鏈。
復(fù)制代碼 代碼如下:
Async.chain = function() {
var chain = new Async.Operation({ chain: true });
return chain;
};
Async.go = function(initialArgument) {
return Async.chain().go(initialArgument);
}
在這里我們可以看到,鏈?zhǔn)秸{(diào)用本身也是一個Async.Operation,鏈?zhǔn)秸{(diào)用所需的go方法和next方法都是在Async.Operation上面做的擴(kuò)展,并且這個擴(kuò)展不會很難,這將在下一小節(jié)說明。
擴(kuò)展方法
我們都知道,通過addCallback方法添加的回調(diào)函數(shù)是會被逐一執(zhí)行的,至少同步函數(shù)如此,因此我們可以用Async.Operation的這一特性來維護(hù)異步調(diào)用隊列,前提是我們?yōu)樗由蠈Ξ惒秸{(diào)用進(jìn)行隊列的支持。
對于異步調(diào)用進(jìn)行隊列的支持,我們稍后再來處理,首先我們利用現(xiàn)成的addCallback方法和yield方法擴(kuò)展出go方法和next方法。
復(fù)制代碼 代碼如下:
this.go = function(initialArgument) {
return this.yield(initialArgument);
}
this.next = function(nextFunction) {
return this.addCallback(nextFunction);
};
實際上,go方法和next方法直接調(diào)用的正是yield方法和addCallback方法。go方法的語義與yield方法一樣,傳遞一個參數(shù)給Async.Operation實例,并且啟動調(diào)用隊列。同時,next方法的語義和addCallback方法,添加一個調(diào)用到隊列的末端。
異步隊列
如何才能讓原本僅支持同步的隊列變得也支持異步?這需要檢測隊列中的每一個調(diào)用的返回,如果返回類型為Async.Operation,我們知道是異步調(diào)用,從而使用特殊的方法等它執(zhí)行完后再執(zhí)行下去。
復(fù)制代碼 代碼如下:
callbackResult = callback(self.result);
self.result = callbackResult;
if (callbackResult && callbackResult instanceof Async.Operation) {
innerChain = Async.chain();
while (callbackQueue.length > 0) {
innerChain.next(callbackQueue.shift());
}
innerChain.next(function(result) {
self.result = result;
self.state = "completed";
self.completed = true;
return result;
});
callbackResult.addCallback(function(result) {
self.result = result;
innerChain.go(result);
});
}
如果調(diào)用返回了一個Async.Operation實例,我們就利用它自身的addCallback方法幫我們執(zhí)行隊列中余下的調(diào)用。準(zhǔn)確來說,是我們構(gòu)造了一個新的調(diào)用鏈,把隊列余下的調(diào)用都轉(zhuǎn)移到新的調(diào)用鏈上,然后讓當(dāng)前異步調(diào)用在回調(diào)中啟動這個新的調(diào)用鏈。
此外還有一些地方我們需要略作修改,以兼容新的異步調(diào)用隊列的。例如result、state、completed的狀態(tài)變更,在鏈?zhǔn)秸{(diào)用中是有所不同的。
小結(jié)
我們在原有的Async.Operation上略作修改,使得它支持異步調(diào)用隊列,完整的代碼看這里:支持鏈?zhǔn)秸{(diào)用的異步調(diào)用框架Async.Operation。
現(xiàn)在我們已經(jīng)擁有了一個功能強(qiáng)大的Async.Operation,接下來我們就要看看如何將它投入到更多常見的使用模式中去
您可能感興趣的文章:
- JavaScript鏈?zhǔn)秸{(diào)用原理與實現(xiàn)方法詳解
- 《javascript設(shè)計模式》學(xué)習(xí)筆記四:Javascript面向?qū)ο蟪绦蛟O(shè)計鏈?zhǔn)秸{(diào)用實例分析
- 在JavaScript中實現(xiàn)鏈?zhǔn)秸{(diào)用的實現(xiàn)
- JavaScript的級聯(lián)函數(shù)用法簡單示例【鏈?zhǔn)秸{(diào)用】
- JavaScript鏈?zhǔn)秸{(diào)用實例淺析
- javascript簡單鏈?zhǔn)秸{(diào)用案例分析
- 學(xué)習(xí)JavaScript設(shè)計模式(鏈?zhǔn)秸{(diào)用)
- JavaScript DSL 流暢接口(使用鏈?zhǔn)秸{(diào)用)實例
- JS鏈?zhǔn)秸{(diào)用的實現(xiàn)方法
- JavaScript中兩種鏈?zhǔn)秸{(diào)用實現(xiàn)代碼
- javascript中的鏈?zhǔn)秸{(diào)用
- javascript 支持鏈?zhǔn)秸{(diào)用的異步調(diào)用框架Async.Operation
- 詳解JavaScript中的鏈?zhǔn)秸{(diào)用
相關(guān)文章
js函數(shù)的引用, 關(guān)于內(nèi)存的開銷
函數(shù)的引用, 對于內(nèi)存的開銷分析,需要的朋友可以參考下2012-09-09JS?TypeScript的Map對象及聯(lián)合類型實戰(zhàn)
這篇文章主要介紹了JS?TypeScript的Map對象及聯(lián)合類型實戰(zhàn),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-08-08JavaScript數(shù)據(jù)結(jié)構(gòu)之棧實例用法
在本篇文章里小編給大家分享了關(guān)于JavaScript數(shù)據(jù)結(jié)構(gòu)之棧實例用法內(nèi)容,有興趣的朋友們學(xué)習(xí)下。2019-01-01js利用數(shù)組length屬性清空和截短數(shù)組的小例子
這篇文章主要介紹了js利用數(shù)組length屬性清空和截短數(shù)組的小例子,有需要的朋友可以參考一下2014-01-01JavaScript算法學(xué)習(xí)之冒泡排序和選擇排序
這篇文章主要給大家介紹了關(guān)于JavaScript算法學(xué)習(xí)之冒泡排序和選擇排序的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者使用JavaScript具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11React?diff算法面試考點(diǎn)超詳細(xì)講解
渲染真實DOM的開銷很大,有時候我們修改了某個數(shù)據(jù),直接渲染到真實dom上會引起整個dom樹的重繪和重排。我們希望只更新我們修改的那一小塊dom,而不是整個dom,diff算法就幫我們實現(xiàn)了這點(diǎn)。diff算法的本質(zhì)就是:找出兩個對象之間的差異,目的是盡可能做到節(jié)點(diǎn)復(fù)用2022-12-12