自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

JavaScript異步調(diào)用框架的jQuery風(fēng)格鏈?zhǔn)秸{(diào)用

開發(fā) 前端
本文描述JavaScript異步調(diào)用框架的鏈?zhǔn)秸{(diào)用。簡單的異步調(diào)用框架順序執(zhí)行的異步函數(shù)需要用嵌套的方式來聲明。但在現(xiàn)實(shí)開發(fā)中,要按順序執(zhí)行一系列的同步異步操作又是很常見的。這就需要設(shè)計(jì)一種新的操作方式來優(yōu)化代碼可讀性。

我們已經(jīng)實(shí)現(xiàn)了一個(gè)簡單的JavaScript異步調(diào)用框架,然而還有一些美中不足,那就是順序執(zhí)行的異步函數(shù)需要用嵌套的方式來聲明。

現(xiàn)實(shí)開發(fā)中,要按順序執(zhí)行一系列的同步異步操作又是很常見的。還是用百度Hi網(wǎng)頁版中的例子,我們先要異步獲取聯(lián)系人列表,然后再異步獲取每一個(gè)聯(lián)系人的具體信息,而且后者是分頁獲取的,每次請求發(fā)送10個(gè)聯(lián)系人的名稱然后取回對應(yīng)的具體信息。這就是多個(gè)需要順序執(zhí)行的異步請求。

為此,我們需要設(shè)計(jì)一種新的操作方式來優(yōu)化代碼可讀性,讓順序異步操作代碼看起來和傳統(tǒng)的順序同步操作代碼一樣優(yōu)雅。

傳統(tǒng)做法

大多數(shù)程序員都能夠很好的理解順序執(zhí)行的代碼,例如這樣子的:

  1. var firstResult = firstOperation(initialArgument);  
  2. var secondResult = secondOperation(firstResult);  
  3. var finalResult = thirdOperation(secondResult);  
  4. alert(finalResult); 

其中先執(zhí)行的函數(shù)為后執(zhí)行的函數(shù)提供所需的數(shù)據(jù)。然而使用我們的JavaScript異步調(diào)用框架后,同樣的邏輯必須變成這樣子:

  1. firstAsyncOperation(initialArgument).addCallback(function(firstResult) {  
  2.   secondAsyncOperation(firstResult).addCallback(function(secondResult) {  
  3.     thirdAsyncOperation(secondResult).addCallback(function(finalResult) {    
  4.       alert(finalResult);  
  5.     });  
  6.   });  
  7. }); 

鏈?zhǔn)綄懛?/STRONG>

我認(rèn)為上面的代碼實(shí)在是太不美觀了,并且希望能夠改造為jQuery風(fēng)格的鏈?zhǔn)綄懛?。為此,我們先?gòu)造一個(gè)用例:

  1. Async.go(initialArgument)  
  2.   .next(firstAsyncOperation)  
  3.   .next(secondAsyncOperation)  
  4.   .next(thirdAsyncOperation)  
  5.   .next(function(finalResult) { alert(finalResult); }) 

在這個(gè)用例當(dāng)中,我們在go傳入初始化數(shù)據(jù),然后每一個(gè)next后面?zhèn)魅胍粋€(gè)數(shù)據(jù)處理函數(shù),這些處理函數(shù)按順序?qū)?shù)據(jù)進(jìn)行處理。

同步并存

上面的用例調(diào)用到的全部都是異步函數(shù),不過我們***能夠兼容同步函數(shù),讓使用者無需關(guān)心函數(shù)的具體實(shí)現(xiàn),也能使用這項(xiàng)功能。為此我們再寫一個(gè)這樣的用例:

  1. Async.go(0)  
  2.   .next(function(i) { alert(i); return i + 1; })  
  3.   .next(function(i) {  
  4.     alert(i);  
  5.     var operation = new Async.Operation();  
  6.     setTimeout(function() { operation.yield(i + 1); }, 1000);  
  7.     return operation;  
  8.   })  
  9.   .next(function(i) { alert(i); return i + 1; })  
  10.   .next(function(i) { alert(i); return i; }); 

在上述用例中,我們期待能夠看到0, 1, 2, 3的提示信息序列,并且1和2之間間隔為1000毫秒。

異步本質(zhì)

一個(gè)鏈?zhǔn)秸{(diào)用,本質(zhì)上也是一個(gè)異步調(diào)用,所以它返回的也是一個(gè)Operation實(shí)例。這個(gè)實(shí)例自然也有result、state和completed這幾個(gè)字段,并且當(dāng)整個(gè)鏈?zhǔn)秸{(diào)用完成時(shí),result等于***一個(gè)調(diào)用返回的結(jié)果,而completed自然是等于true。

我們可以擴(kuò)展一下上一個(gè)用例,得到如下用例代碼:

  1. var chainOperation = Async.go(0)  
  2.   .next(function(i) { alert(i); return i + 1; })  
  3.   .next(function(i) {  
  4.     alert(i);  
  5.     var operation = new Async.Operation();  
  6.     setTimeout(function() { operation.yield(i + 1); }, 1000);  
  7.     return operation;  
  8.   })  
  9.   .next(function(i) { alert(i); return i + 1; })  
  10.   .next(function(i) { alert(i); return i; });  
  11.  
  12. setTiemout(function() { alert(chainOperation.result; }, 2000);  

把鏈?zhǔn)秸{(diào)用的返回保存下來,在鏈?zhǔn)秸{(diào)用完成時(shí),它的result應(yīng)該與***一個(gè)操作的返回一致。在上述用例中,也就是3。

調(diào)用時(shí)機(jī)

盡管我們提供了一種鏈?zhǔn)秸{(diào)用方式,但是用戶不一定會(huì)按照這種固定的方式來調(diào)用,所以我們?nèi)匀灰紤]兼容用戶的各種可能用法,例如說異步地用next往調(diào)用鏈添加操作:

  1. var chainOperation = Async.go(0);  
  2. chainOperation.next(function(i) { alert(i); return i + 1; });  
  3. setTimeout(function() {  
  4.   chainOperation.next(function(i) {  
  5.     alert(i);  
  6.     var operation = new Async.Operation();  
  7.     setTimeout(function() { operation.yield(i + 1); }, 2000);  
  8.     return operation;  
  9.   })  
  10. }, 1000);  
  11. setTimeout(function() {  
  12.   chainOperation.next(function(i) { alert(i); return i + 1; });  
  13. }, 2000); 

在這個(gè)用例當(dāng)中,用戶每隔1000毫秒添加一個(gè)操作,而其中第二個(gè)操作耗時(shí)2000毫秒。也就是說,添加第三個(gè)操作時(shí)第二個(gè)操作還沒返回。作為一個(gè)健壯的框架,必須要能兼容這樣的使用方式。

此外我們還要考慮,用戶可能想要先構(gòu)造調(diào)用鏈,然后再執(zhí)行調(diào)用鏈。這時(shí)候用戶就會(huì)先使用next方法添加操作,再使用go方法執(zhí)行。

  1. var chainOperation = Async  
  2.   .chain(function(i) { alert(i); return i + 1; })  
  3.   .next(function(i) {  
  4.     alert(i);  
  5.     var operation = new Async.Operation();  
  6.     setTimeout(function() { operation.yield(i + 1); }, 2000);  
  7.     return operation;  
  8.   })  
  9.   .go(0)  
  10. setTimeout(function() {  
  11.   chainOperation.next(function(i) { alert(i); return i + 1; })  
  12. }, 1000); 

在上述用例中,用戶通過chain和next添加了頭同步操作和異步操作各一個(gè),然后用go執(zhí)行調(diào)用鏈,在調(diào)用鏈執(zhí)行完畢之前又用next異步追加了一個(gè)操作。一個(gè)健壯的框架,在這樣的用例當(dāng)中應(yīng)該能夠如同用戶所期望的那樣提示0, 1, 2。

小結(jié)

針對鏈?zhǔn)秸{(diào)用的需求,我們設(shè)計(jì)了如此多的用例,包括各種奇怪的JavaScript異步調(diào)用方式。具體實(shí)現(xiàn)方法,將在下文中講述。

【編輯推薦】

  1. JavaScript異步調(diào)用框架的代碼實(shí)現(xiàn)
  2. JavaScript異步調(diào)用框架用例設(shè)計(jì)
  3. JavaScript異步調(diào)用框架問題描述
  4. 淺談如何用Javascript+VML實(shí)現(xiàn)流程設(shè)計(jì)器
  5. 常用的JavaScript驗(yàn)證正則表達(dá)式
責(zé)任編輯:yangsai 來源: Cat in dotNET
相關(guān)推薦

2009-07-01 14:37:14

JavaScript異

2009-07-01 13:58:00

JavaScript異

2009-07-01 14:23:46

JavaScript異

2009-07-01 14:05:23

JavaScript異

2009-10-20 16:48:30

C#委托

2011-03-02 08:57:22

jQueryJavaScript

2009-12-21 14:10:26

WCF異步調(diào)用

2009-11-09 10:50:30

WCF異步調(diào)用

2021-03-29 09:26:44

SpringBoot異步調(diào)用@Async

2009-11-06 15:54:15

WCF異步調(diào)用

2009-08-21 11:02:55

C#異步調(diào)用

2024-07-31 15:57:41

2024-10-15 10:28:43

2009-08-21 11:24:16

C#異步調(diào)用

2010-02-22 13:28:05

WCF異步調(diào)用

2022-07-01 08:14:28

Dubbo異步代碼

2012-10-29 10:59:27

Windows 8

2009-12-07 14:26:47

WCF異步調(diào)用

2009-12-07 14:35:42

WCF異步調(diào)用

2010-01-11 17:24:19

VB.NET異步調(diào)用
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)