一些讓大家把AJAX寫得更好的小技巧
一直以來,在網路上我看到大家普遍都用jQuery的$.ajax()
函式來請求AJAX
$.ajax({
data: Data,
dataType: 'json',
url: '/path',
success: (res, status, jqXHR)=>{
// 成功請求AJAX
console.log('AJAX call successful.');
console.log(res);
},
error: (jqXHR, status, e)=>{
// AJAX請求發生錯誤
console.log('AJAX call failed.');
console.log(status + ': ' + e);
},
complete: ()=>{
// 完成AJAX請求(無論成功或失敗都會執行)
console.log('AJAX call completed');
};
});
雖然在初學的時候應該會有點難懂,但弄清楚後會覺得很簡單。但是,這樣的code看起來還是有些缺點:
- 嵌套過多 AJAX所返回的數據將被封裝於success進程中,因為ajax他本質上是一種異步通訊。此外,還會降低代碼的可讀性。
- 沒有鏈結或組合 因為每個請求都是異步的緣故,我們無法預測多個AJAX返回的結果。
- 已棄用 雖然跟前面的範例程式無關,但在jQuery v1.8及之後的版本
jqXHR.success()、jqXHR.error()、jqXHR.complete()
等...已被正式棄用。
Promises and deferred
好在,在原生$.ajax()
中,你現在可以使用鏈方法取代jqXHR.success()
等
和其他jQuery程式的寫法一樣,可以使用鏈方法實作
$.ajax({
data: Data,
dataType: 'json',
url: '/path'
}).done(function(res) {
// 成功
console.log(res);
}).fail(function(jqXHR, status, e) {
// 失敗
console.log(status + ': ' + e);
});
此外,你還可以將$.ajax()
指派給一個變數,這樣可以callback他的回傳值
你自然可以使用鏈方法,畢竟,他是jQuery標誌性的語法
var ajaxCall = $.ajax({
context: $(element),
data: Data,
dataType: 'json',
url: '/path'
});
ajaxCall.done(function(res) {
console.log(res);
});
雖然這個.done()
看起來影響不大,但如果在很多異步請求的情況下,他不需複雜嵌套的特性能大大增加代碼的可讀性
理所當然地,你可以在ajax請求本身與更進一步的動作中,插入其他的程式碼
多重ajax請求
你可以使用$.when()監聽多個ajax進程的狀態
var t1 = $.ajax({...}),
t2 = $.ajax({...});
$.when(t1, t2).done((r1, r2)=>{
// 回傳的結果將會是一個陣列:
// [data, textStatus, jqXHR]
// 如果想獲取t1的回傳資料,可以使用r1[0]
console.log(r1[0]);
console.log(r2[0]);
});
ajax請求的關係鏈
你可以鏈結多個ajax請求,把第一個請求的回傳值傳遞給下一個請求。最後,你可以使用.done()處理回傳結果
var t1 = $.ajax({
url: '/API',
dataType: 'json'
}),
t2 = t1.then((data)=>{
return $.ajax({
url: '/another/API',
dataType: 'json',
data: data.sessionID
});
});
t2.done((res)=>{
console.log(res);
});
ajax的模組化
假如你今天要進行兩次 AJAX 調用,除了 data 和 url 參數外,其他參數都相同的話,模組化便可派上用場了。
// 進行 AJAX 請求的函數
var fetchData = function(query, dataURL) {
// 回傳 $.ajax promise
return $.ajax({
data: query,
dataType: 'json',
url: dataURL
});
}
// AJAX 請求
// 1. Get student Name
// 2 Get student ID
var getName = fetchData({
'hash': 'f6c7b81179bef074d36f9727efde8dc3',
'email': '[email protected]'
}, '/API_1'),
getID = fetchData({
'email': '[email protected]'
}, '/API_2');
// 用 $.when 檢查兩個 AJAX 的請求是否成功
$.when(getName, getID).then(function(Name, ID) {
console.log(name.data);
console.log(ID.data);
});
上面的方法便可以成功減少AJAX的嵌套,降低程式碼的複雜度
結語
玩家與遊戲伺服器的通訊方式常分成兩類:強聯網和弱聯網。
我們常說,強聯網就是Socket,具有實時性、長連線,舉個例子就像是FPS遊戲或MMORPG等,需要伺服器實時處裡並告訴玩家其他玩家的資訊。
而弱聯網則是純HTTP協議,只用Post和Get來通訊,由於每次連線只處理一個請求,當伺服器處理完客戶端的請求便馬上斷開連線,節省傳輸時間和伺服器成本。比較知名的就是像神魔之塔、龍族拼圖,兩個遊戲只在進入關卡前和關卡完成的結算時與伺服器通訊。
今天提及的AJAX便屬於弱聯網,而這樣的非同步請求則因為無刷新的特色而知名。
資料來源於網路。