[jQuery] 關於AJAX的小技巧

一些讓大家把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看起來還是有些缺點:

  1. 嵌套過多 AJAX所返回的數據將被封裝於success進程中,因為ajax他本質上是一種異步通訊。此外,還會降低代碼的可讀性。
  2. 沒有鏈結或組合 因為每個請求都是異步的緣故,我們無法預測多個AJAX返回的結果。
  3. 已棄用 雖然跟前面的範例程式無關,但在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便屬於弱聯網,而這樣的非同步請求則因為無刷新的特色而知名。

資料來源於網路。

按讚

發佈留言

%d 位部落客按了讚: