天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

JavaScript 異步調用框架 (Part 4 - 鏈式調用)

現實開發中,要按順序執行一系列的同步異步操作又是很常見的。還是用百度Hi網頁版中的例子,我們先要異步獲取聯系人列表,然后再異步獲取每一個聯系人的具體信息,而且后者是分頁獲取的,每次請求發送10個聯系人的名稱然后取回對應的具體信息。這就是多個需要順序執行的異步請求。
為此,我們需要設計一種新的操作方式來優化代碼可讀性,讓順序異步操作代碼看起來和傳統的順序同步操作代碼一樣優雅。
傳統做法
大多數程序員都能夠很好的理解順序執行的代碼,例如這樣子的:
復制代碼 代碼如下:
var firstResult = firstOperation(initialArgument);
var secondResult = secondOperation(firstResult);
var finalResult = thirdOperation(secondResult);
alert(finalResult);

其中先執行的函數為后執行的函數提供所需的數據。然而使用我們的異步調用框架后,同樣的邏輯必須變成這樣子:
復制代碼 代碼如下:
firstAsyncOperation(initialArgument).addCallback(function(firstResult) {
secondAsyncOperation(firstResult).addCallback(function(secondResult) {
thirdAsyncOperation(secondResult).addCallback(function(finalResult) {
alert(finalResult);
});
});
});

鏈式寫法
我認為上面的代碼實在是太不美觀了,并且希望能夠改造為jQuery風格的鏈式寫法。為此,我們先構造一個用例:
復制代碼 代碼如下:
Async.go(initialArgument)
.next(firstAsyncOperation)
.next(secondAsyncOperation)
.next(thirdAsyncOperation)
.next(function(finalResult) { alert(finalResult); })

在這個用例當中,我們在go傳入初始化數據,然后每一個next后面傳入一個數據處理函數,這些處理函數按順序對數據進行處理。
同步并存
上面的用例調用到的全部都是異步函數,不過我們最好能夠兼容同步函數,讓使用者無需關心函數的具體實現,也能使用這項功能。為此我們再寫一個這樣的用例:
復制代碼 代碼如下:
Async.go(0)
.next(function(i) { alert(i); return i + 1; })
.next(function(i) {
alert(i);
var operation = new Async.Operation();
setTimeout(function() { operation.yield(i + 1); }, 1000);
return operation;
})
.next(function(i) { alert(i); return i + 1; })
.next(function(i) { alert(i); return i; });

在上述用例中,我們期待能夠看到0, 1, 2, 3的提示信息序列,并且1和2之間間隔為1000毫秒。
異步本質
一個鏈式調用,本質上也是一個異步調用,所以它返回的也是一個Operation實例。這個實例自然也有result、state和completed這幾個字段,并且當整個鏈式調用完成時,result等于最后一個調用返回的結果,而completed自然是等于true。
我們可以擴展一下上一個用例,得到如下用例代碼:
復制代碼 代碼如下:
var chainOperation = Async.go(0)
.next(function(i) { alert(i); return i + 1; })
.next(function(i) {
alert(i);
var operation = new Async.Operation();
setTimeout(function() { operation.yield(i + 1); }, 1000);
return operation;
})
.next(function(i) { alert(i); return i + 1; })
.next(function(i) { alert(i); return i; });
setTiemout(function() { alert(chainOperation.result; }, 2000);

把鏈式調用的返回保存下來,在鏈式調用完成時,它的result應該與最后一個操作的返回一致。在上述用例中,也就是3。
調用時機
盡管我們提供了一種鏈式調用方式,但是用戶不一定會按照這種固定的方式來調用,所以我們仍然要考慮兼容用戶的各種可能用法,例如說異步地用next往調用鏈添加操作:
復制代碼 代碼如下:
var chainOperation = Async.go(0);
chainOperation.next(function(i) { alert(i); return i + 1; });
setTimeout(function() {
chainOperation.next(function(i) {
alert(i);
var operation = new Async.Operation();
setTimeout(function() { operation.yield(i + 1); }, 2000);
return operation;
})
}, 1000);
setTimeout(function() {
chainOperation.next(function(i) { alert(i); return i + 1; });
}, 2000);

在這個用例當中,用戶每隔1000毫秒添加一個操作,而其中第二個操作耗時2000毫秒。也就是說,添加第三個操作時第二個操作還沒返回。作為一個健壯的框架,必須要能兼容這樣的使用方式。
此外我們還要考慮,用戶可能想要先構造調用鏈,然后再執行調用鏈。這時候用戶就會先使用next方法添加操作,再使用go方法執行。
復制代碼 代碼如下:
var chainOperation = Async
.chain(function(i) { alert(i); return i + 1; })
.next(function(i) {
alert(i);
var operation = new Async.Operation();
setTimeout(function() { operation.yield(i + 1); }, 2000);
return operation;
})
.go(0)
setTimeout(function() {
chainOperation.next(function(i) { alert(i); return i + 1; })
}, 1000);

在上述用例中,用戶通過chain和next添加了頭同步操作和異步操作各一個,然后用go執行調用鏈,在調用鏈執行完畢之前又用next異步追加了一個操作。一個健壯的框架,在這樣的用例當中應該能夠如同用戶所期望的那樣提示0, 1, 2。
小結
針對鏈式調用的需求,我們設計了如此多的用例,包括各種奇怪的異步調用方式。最終如何實現這樣的功能呢?

JavaScript技術JavaScript 異步調用框架 (Part 4 - 鏈式調用),轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 男人边吃奶边挵进去呻吟漫画 | 免费毛片网站在线观看 | 恋孩癖网站大全在线观看 | 99热婷婷国产精品综合 | 中文中幕无码亚洲视频 | zxfuli午夜福利在线 | 麻豆AV久久无码精品九九 | 少妇连续高潮抽搐痉挛昏厥 | 特级做A爰片毛片免费看108 | av免费网站不卡观看 | 69日本人xxxx16—18| 国产偷国产偷亚州清高 | 城中村快餐嫖老妇对白 | 久青草影院 | 久久久久久亚洲精品影院 | 国产乱妇乱子在线播视频播放网站 | 欧美精品AV精品一区视频 | 小夫妻天天恶战 | 久久黄色大片 | 国产99久9在线 | 黄色三级视频在线观看 | 亚洲欭美日韩颜射在线二 | 红桃传媒少妇人妻网站无码抽插 | RUN AWAY无删减全集动漫 | 伊人久久综合成人亚洲 | 亚洲字幕久久 | 亚洲 欧美 日韩 精品 自拍 | 亚洲理论片在线中文字幕 | 中文日产无乱码AV在线观 | 成人免费一级毛片在线播放视频 | 拍床戏被肉高H纯肉H在水 | 99国产精品久久人妻 | 好男人好资源在线播放 | 推倒美女总裁啪啪 | 九色PORNY真实丨首页 | 久久99国产精品自在自在 | 69ZXX少妇内射无码 | 麻豆AV无码精品一区二区 | 国产成人亚洲精品无广告 | 啪啪激情婷婷久久婷婷色五月 | 国产99热在线观看 |