簡體   English   中英

使用promise Q庫實現異步JavaScript編程的最佳實踐

[英]Best practices for implementing asynchronous javascript programming with promise Q library

已經在JS中有一個層,它通過以下實現幫助獲取和發布到服務器:

var getJson = function(url, callback, onError) {
    $.get(url)
    .done(function(data) {
        if(callback != null)
            callback(data);
    })
    .fail (function(error) {
        if(onError != null)
            onError (error);
        else
            my.notification.notifyError(onErrorMessage);
    });
};

var postJSON = function(url, data, callback, onError) {
    $.ajax({
        url : url ,
        type: "POST" ,
        contentType : "application/json"
        dataType : "json" ,
        date : ko.toJSON(data)
    })
    .done(function(data) {
        if(callback ! = null)
            callback(data);
    })
    .fail(function(error) {
        if(onError ! = null)
            onError (error);
        else
            my.notification.notifyError(onErrorMessage);
    });
};

在DataService層上使用這些實現:

// Get
var find = function(date, onSuccess , onError) {
   var url = /* url with the Controller and Action */ + "?queryString = " + data.filter;
   getJson(url , onSuccess , onError);
};

// Post
var save = function(date, onSuccess , onError) {
    var url = /* url with the Controller and Action */;
    postJSON(url, data, onSuccess, onError);
};

然而,我們使用webapi,在某些情況下,請求取決於另一個生成“金字塔末日”的請求的結果。 為了更優雅的代碼,我們正在實現用於異步編程的庫Q.

使用Q promisses按照上面顯示的模式實現了get as show的新方法:

var getJsonDefer = function(url, callback, onError) {
    return Q.when($.getJSON(url))
    .then (function(data) {
        if(callback ! = null)
            callback(data);
    })
    .fail (function(error) {
        if(onError ! = null)
            onError (error);
        else
            my.notification.notifyError(onErrorMessage);
    });
};

我試圖以這種方式在DataService層上使用此實現:

// Get
var find = function(date, onSuccess , onError) {
   var url = /* url with the Controller and Action */ + "?queryString = " + data.filter;
   return getJsonDefer(url, onSuccess, onError);
};

無論如何在我的圖層viewmodel javascript中假設我需要使用3個查找,一個取決於另一個的結果:

var = dataOne { 
    filter: " Filter"
};

findOne(dataOne,
       function(result) {
            return result;
       }
       function(error) {
           throw error;
       })
       .then(function(args) {
            var = datatwo { 
                filter: args
            };

            // Second
            findTwo(datatwo ,
               function(result) {
                    return result;
               }
               function(error) {
                   throw error;
               }
            );
        })
        .then(function(args) {
            var = dataThree { 
                filter: args
            };

            // Third
            findThree(dataThree,
                function(result) {
                    return result;
                }
                function(error) {
                    throw error;
                }
            );
        }).catch(function(error) {
            // Handle any error from all above steps
        })
        .done();

我的問題 :

我承認我無法以正確的方式實現,因為.then()中的所有函數都帶有未定義的args。

我想知道滿足這里提出的情景的最佳做法是什么。

我想你會發現承諾的吸引力在於你可以用更少的代碼來實現你的目標。 但是,您需要了解一些事項。 首先,您不再需要傳遞或接收回調和錯誤。 您只需確保在處理程序中返回結果或承諾。 這就是值傳播到下一個處理程序的方式。

這是對您的程序的未經測試的修改,應該說明形式:

var find = function(data) {
    var url = /* url with the Controller and Action */ + "?queryString = " + data.filter;
    return Q($.getJson(url));
};

find({filter: "filter"})
.then(function (firstResult) {
    return find({filter: firstResult})
    .then(function (secondResult) {
        return find({filter: secondResult})
        .then(function (thirdResult) {
            return [firstResult, secondResult, thirdResult];
        });
    });
})
.fail(notifyError)
.done();

請注意,任何階段的錯誤都將由底部的單個fail調用處理。 無論最后是否有錯誤處理程序,始終使用done()結束鏈,以便在控制台中顯示之前發生的任何錯誤,即使在fail處理程序中也是如此。

請注意,如果一個操作依賴於前一個操作,並且處理程序需要訪問第一個和第二個結果,則只需要嵌套promise。 如果您只需要第二次操作的結果,您可以直接鏈接。

find({filter: "filter"})
.then(function (firstResult) {
    return find({filter: firstResult})
})
.then(function (secondResult) {
    return find({filter: secondResult})
    .then(function (thirdResult) {
        return [secondResult, thirdResult];
    });
});
.fail(notifyError)
.done();

您也可以拼合事情Q.allpromise.spread ,但我會離開你的文檔,在這一點上,因為我希望,你得到的要點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM