最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript 異步調(diào)用框架 (Part 6 - 實(shí)例 & 模式)

 更新時(shí)間:2009年08月04日 00:15:42   作者:  
我們用了5篇文章來(lái)討論如何編寫(xiě)一個(gè)JavaScript異步調(diào)用框架(問(wèn)題 & 場(chǎng)景、用例設(shè)計(jì)、代碼實(shí)現(xiàn)、鏈?zhǔn)秸{(diào)用、鏈?zhǔn)綄?shí)現(xiàn)),現(xiàn)在是時(shí)候讓我們看一下在各種常見(jiàn)開(kāi)發(fā)情景中如何使用它了。
封裝Ajax
設(shè)計(jì)Async.Operation的最初目的就是解決Ajax調(diào)用需要傳遞callback參數(shù)的問(wèn)題,為此我們先把Ajax請(qǐng)求封裝為Async.Operation。我在這里使用的是jQuery,當(dāng)然無(wú)論你用什么基礎(chǔ)庫(kù),在使用Async.Operation時(shí)都可以做這種簡(jiǎn)單的封裝。
復(fù)制代碼 代碼如下:

var Ajax = {};

Ajax.get = function(url, data) {
var operation = new Async.Operation();
$.get(url, data, function(result) { operation.yield(result); }, "json");
return operation;
};

Ajax.post = function(url, data) {
var operation = new Async.Operation();
$.post(url, data, function(result) { operation.yield(result); }, "json");
return operation;
};

在我所調(diào)用的服務(wù)器端API中,只需要GET和POST,且數(shù)據(jù)都為JSON,所以我就直接把jQuery提供的其它Ajax選項(xiàng)屏蔽掉了,并設(shè)置數(shù)據(jù)類(lèi)型為JSON。在你的項(xiàng)目當(dāng)中,也可以用類(lèi)似的方式將Ajax封裝為若干僅僅返回Async.Operation的方法,將jQuery提供的選項(xiàng)都封裝在Ajax這一層內(nèi),不再向上層暴露這些選項(xiàng)。

調(diào)用Ajax
把Ajax封裝好后,我們就可以開(kāi)始專(zhuān)心寫(xiě)業(yè)務(wù)邏輯了。

假設(shè)我們有一個(gè)Friend對(duì)象,它的get方法用于返回單個(gè)好友對(duì)象,而getAll方法用于返回所有好友對(duì)象。于此對(duì)應(yīng)的是兩個(gè)服務(wù)器端API,friend接口會(huì)返回單個(gè)好友JSON,而friendlist接口會(huì)返回所有好友名稱(chēng)組成的JSON。

首先我們看看較為基礎(chǔ)的get方法怎么寫(xiě):
復(fù)制代碼 代碼如下:

function get(name) {
return Ajax.get("/friend", "name=" + encodeURIComponent(name));
}

就這么簡(jiǎn)單?對(duì)的,假如服務(wù)器端API返回的JSON結(jié)構(gòu)正好就是你要的好友對(duì)象結(jié)構(gòu)的話。如果JSON結(jié)構(gòu)和好友對(duì)象結(jié)構(gòu)是異構(gòu)的,或許你還要加點(diǎn)代碼來(lái)把JSON映射為對(duì)象:
復(fù)制代碼 代碼如下:

function get(name) {
var operation = new Async.Operation()
Ajax.get("/friend", "name=" + encodeURIComponent(name))
.addCallback(function(json) {
operation.yield(createFriendFromJson(json));
});
return operation;
}

Ajax隊(duì)列
接下來(lái)我們要編寫(xiě)的是getAll方法。因?yàn)閒riendlist接口只返回好友名稱(chēng)列表,因此在取得這份列表后我們還要逐一調(diào)用get方法獲取具體的好友對(duì)象??紤]到在同時(shí)進(jìn)行多個(gè)friend接口調(diào)用可能觸發(fā)服務(wù)器的防攻擊策略,導(dǎo)致被關(guān)小黑屋一段時(shí)間,所以對(duì)friend接口的調(diào)用必須排隊(duì)。
復(fù)制代碼 代碼如下:

function getAll(){
var operation = new Async.Operation();
var friends = [];
var chain = Async.chain();
Ajax.get("/friendlist", "")
.addCallback(function(json) {
for (var i = 0; i < json.length; i++) {
chain.next(function() {
return get(json.shift())
.addCallback(function(friend) { friends.push(friend); });
});
}
chain
.next(function() { operation.yield(friends); })
.go();
})
return operation;
}

在這里,我們假設(shè)friendlist接口返回的JSON就是一個(gè)Array,在獲取到這個(gè)Array后構(gòu)造一個(gè)等長(zhǎng)的異步調(diào)用隊(duì)列,其中每一個(gè)調(diào)用的邏輯都是一樣的——取出Array中首個(gè)好友的名稱(chēng),用get方法獲取對(duì)應(yīng)的好友對(duì)象,再將好友對(duì)象放入另一個(gè)Array中。在調(diào)用隊(duì)列的末端,我們?cè)僮芳恿艘粋€(gè)調(diào)用,用于返回保存好友對(duì)象的Array。

在這個(gè)例子當(dāng)中,我們沒(méi)有利用調(diào)用隊(duì)列會(huì)把上一個(gè)函數(shù)的結(jié)果傳遞給下一個(gè)函數(shù)的特性,不過(guò)也足夠展示調(diào)用隊(duì)列的用途了——讓多個(gè)底層為Ajax請(qǐng)求的異步操作按照固定的順序阻塞式執(zhí)行。

由于底層異步函數(shù)返回的就是Async.Operation,你可以直接把它傳遞給next方法,也可以用匿名函數(shù)包裝后傳遞給next方法,而匿名函數(shù)內(nèi)部只需要一個(gè)return。

延時(shí)函數(shù)
在上面的例子中,使用隊(duì)列是為了避免觸發(fā)服務(wù)器的防攻擊策略,但有時(shí)候這還是不夠的。例如說(shuō),服務(wù)器要求兩個(gè)請(qǐng)求之間至少間隔500毫秒,否則就認(rèn)為是攻擊,那么我們就要在隊(duì)列里面插入這個(gè)間隔了。

在原本next方法調(diào)用的匿名函數(shù)中手動(dòng)加入setTimeout是一個(gè)辦法,但為什么我們不寫(xiě)一個(gè)輔助函數(shù)來(lái)解決這類(lèi)問(wèn)題呢?讓我們來(lái)寫(xiě)一個(gè)輔助方法并讓它和Async.Operation無(wú)縫結(jié)合起來(lái)。
復(fù)制代碼 代碼如下:

Async.wait = function(delay, context) {
var operation = new Async.Operation();
setTimeout(function() { operation.yield(context); }, delay);
return operation;
};

Async.Operation.prototype.wait = function(delay, context) {
this.next(function(context) { return Async.wait(delay, context); });
}

在有了這個(gè)輔助方法后,我們就可以在上述getAll方法中輕松實(shí)現(xiàn)在每個(gè)Ajax請(qǐng)求之間間隔500毫秒。在for循環(huán)內(nèi)的加上對(duì)wait的調(diào)用就可以了。
復(fù)制代碼 代碼如下:

for (var i = 0; i < json.length; i++) {
chain
.wait(500)
.next(function() {
return get(json.shift())
.addCallback(function(friend) { friends.push(friend); });
});
}

小結(jié)
通過(guò)一些簡(jiǎn)單的例子,我們了解到了Async.Operation常見(jiàn)的使用方式,以及在有需要的時(shí)候如何擴(kuò)展它的功能。希望Async.Operation能夠有效幫助大家提高Ajax應(yīng)用的代碼可讀性。

相關(guān)文章

  • 使用canvas實(shí)現(xiàn)鯉魚(yú)躍龍門(mén)的動(dòng)畫(huà)效果

    使用canvas實(shí)現(xiàn)鯉魚(yú)躍龍門(mén)的動(dòng)畫(huà)效果

    這篇文章主要給大家介紹了使用canvas實(shí)現(xiàn)鯉魚(yú)躍龍門(mén)的動(dòng)畫(huà)效果,文中通過(guò)代碼示例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,感興趣的小伙伴可以自己動(dòng)手嘗試一下
    2024-02-02
  • JS中appendChild追加子節(jié)點(diǎn)無(wú)效的解決方法

    JS中appendChild追加子節(jié)點(diǎn)無(wú)效的解決方法

    這篇文章主要給大家介紹了關(guān)于JS中appendChild追加子節(jié)點(diǎn)無(wú)效的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)
    2018-10-10
  • js模擬淘寶網(wǎng)的多級(jí)選擇菜單實(shí)現(xiàn)方法

    js模擬淘寶網(wǎng)的多級(jí)選擇菜單實(shí)現(xiàn)方法

    這篇文章主要介紹了js模擬淘寶網(wǎng)的多級(jí)選擇菜單實(shí)現(xiàn)方法,涉及javascript針對(duì)頁(yè)面元素結(jié)點(diǎn)的遍歷與設(shè)置等操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-08-08
  • 使用element-ui的upload組件上傳代碼包時(shí)遇到的問(wèn)題小結(jié)

    使用element-ui的upload組件上傳代碼包時(shí)遇到的問(wèn)題小結(jié)

    這篇文章主要介紹了使用element-ui的upload組件上傳代碼包時(shí)遇到的問(wèn)題及總結(jié),本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • php 中序列化和json使用介紹

    php 中序列化和json使用介紹

    序列化是將對(duì)象狀態(tài)轉(zhuǎn)換為可保持或可傳輸?shù)母袷降倪^(guò)程。與序列化相對(duì)的是反序列化,它將流轉(zhuǎn)換為對(duì)象。這兩個(gè)過(guò)程結(jié)合起來(lái),可以輕松地存儲(chǔ)和傳輸數(shù)據(jù)
    2013-07-07
  • js快速排序的實(shí)現(xiàn)代碼

    js快速排序的實(shí)現(xiàn)代碼

    快速排序是一種平均性能非常優(yōu)秀的排序算法,在很多場(chǎng)合都會(huì)應(yīng)用到他,了解快速排序于對(duì)開(kāi)放高效率的軟件有很重要的作用
    2013-12-12
  • js獲取url中的參數(shù)且參數(shù)為中文時(shí)通過(guò)js解碼

    js獲取url中的參數(shù)且參數(shù)為中文時(shí)通過(guò)js解碼

    這篇文章主要介紹了url中傳遞中文參數(shù)的時(shí)候通過(guò)js解碼,需要的朋友可以參考下
    2014-03-03
  • js tab欄切換代碼實(shí)例解析

    js tab欄切換代碼實(shí)例解析

    這篇文章主要介紹了js tab欄切換代碼實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • JS文件中加載jquery.js的實(shí)例代碼

    JS文件中加載jquery.js的實(shí)例代碼

    這篇文章主要介紹了JS文件中加載jquery.js的方法,JS文件添加其他JS的實(shí)例代碼,感興趣的小伙伴們可以參考一下,具體如下
    2018-05-05
  • 借助javascript代碼判斷網(wǎng)頁(yè)是靜態(tài)還是偽靜態(tài)

    借助javascript代碼判斷網(wǎng)頁(yè)是靜態(tài)還是偽靜態(tài)

    如何看同類(lèi)型的網(wǎng)站采用的是靜態(tài)還是偽靜態(tài),一般網(wǎng)頁(yè)后綴都是以.html結(jié)尾。我們可以借助一段簡(jiǎn)單的javascript代碼判斷一下
    2014-05-05

最新評(píng)論

贵定县| 繁昌县| 桐庐县| 梧州市| 策勒县| 桦南县| 漠河县| 永年县| 遵化市| 长武县| 罗定市| 扎囊县| 年辖:市辖区| 绥阳县| 湖北省| 琼结县| 永兴县| 金华市| 博湖县| 太康县| 景德镇市| 慈溪市| 延安市| 赫章县| 乐清市| 秦安县| 吉安县| 金塔县| 亳州市| 麟游县| 望奎县| 二连浩特市| 宜君县| 江山市| 重庆市| 和田县| 四平市| 驻马店市| 长治市| 乐清市| 石门县|