熟練使用使用jQuery Promise (Deferred)

wangduanduan發表於2016-10-25

1 情景再現

以前用nodejs寫後端程式時,遇到Promise這個概念,這個東西好呀!不用謝一層一層回撥,直接用類似於jQuery的連綴方式。後來遇到bluebird這個庫,它就是Promise庫中很有名的。我希望可以把Promise用在前端的ajax請求上,但是我不想又引入bluebird。後來發現,jquery本身就具有類似於Promise的東西。於是我就jquery的Promise寫一些非同步請求。

2 不堪回首

看看一看我以前寫非同步請求的方式

// 函式定義
function sendRequest(req,successCallback,errorCallback){
    $.ajax({
        ...
        ...
        success:function(res){
            successCallback(res);
        },
        error:function(res){
            errorCallback(res);
        }
    });
}

// 函式呼叫,這個函式的匿名函式寫的時候很容易出錯,而且有時候難以理解
sendRequest(req,function(res){
    //請求成功
    ...
},function(res){
    //請求失敗
    ...
});

3 面朝大海

下面是我希望的非同步呼叫方式

sendRequest(req)
.done(function(res){
    //請求成功
    ...
})
.fail(function(req){
    //請求失敗
    ...
});

4 廢話少說,放‘碼’過來

talk is cheap, show me the code

// 最底層的傳送非同步請求,做成Promise的形式

App.addMethod(`_sendRequest`,function(path,method,payload){
    var dfd = $.Deferred();
    $.ajax({
        url:path,
        type:method || "get",
        headers:{
            sessionId:session.id || ``
        },
        data:JSON.stringify(payload),
        dataType:"json",
        contentType : `application/json; charset=UTF-8`,
        success:function(data){
            dfd.resolve(data);
        },
        error:function(data){
            dfd.reject(data);
        }
    });
    return dfd.promise();
});

//根據callId查詢錄音檔案,不僅僅是非同步請求可以做成Promise形式,任何函式都可以做成Promise形式
App.addMethod(`_getRecordingsByCallId`,function(callId){
    var dfd = $.Deferred(),
        path = `/api/tenantcalls/`+callId+`/recordings`;

    App._sendRequest(path)
    .done(function(res){dfd.resolve(res);})
    .fail(function(res){dfd.reject(res);});

    return dfd.promise();
});

// 獲取錄音
App.addMethod(`getCallDetailRecordings`,function(callId){
    App._getRecordingsByCallId(callId)
    .done(function(res){
        // 獲取結果後渲染資料
        App.renderRecording(res);
    })
    .fail(function(res){
        App.error(res);
    });
});

5 注意事項

  • jQuery的Promise主要是用了jQquery的$.Derferred()方法,一些老版本的jquery並不支援此方法。
  • jQuery版本必須大於等於1.5,推薦使用1.11.3

6 參考文獻

7 最後

以上文章僅供參考,不包完全正確。歡迎評論,3q。

相關文章