2011-12-20 21 views
0

我一直在閱讀有關jQuery的延期,但我不能完全理解如何使用它們。使用jQuery的延期

我有以下的深度嵌套代碼

Repository.Projects.GetStages(function (data) { 
    var stagesXml = $.parseXML(data.d); 

    Repository.Projects.GetBenefits(function (data) { 
     var benefitsXml = $.parseXML(data.d); 

     Repository.Projects.GetPriorities(function (data) { 
      var prioritiesXml = $.parseXML(data.d); 

      Repository.Projects.GetDifficulties(function (data) { 
       var difficultiesXml = $.parseXML(data.d); 

       Repository.Projects.GetFactors(function (data) { 
        var factorsXml = $.parseXML(data.d); 

        Repository.Projects.GetRatings(function (data) { 
         var ratingsXml = $.parseXML(data.d); 

         Repository.Projects.GetProjectRatings(selectedPersonIdEncrypted, passDate, function (data) { 
          var dataDoc = UTL.Utility.prototype.setDomDocument(data.d); 
          var xsltDoc = UTL.Utility.prototype.setXslt("Xslt/UserRating/ProjectRatings.xslt"); 
          var html = UTL.Utility.prototype.transform(dataDoc, xsltDoc, [ 
           ['stages', stagesXml], 
           ['benefits', benefitsXml], 
           ['priorities', prioritiesXml], 
           ['difficulties', difficultiesXml], 
           ['factors', factorsXml], 
           ['ratings', ratingsXml] 
          ]); 

          $('#Project', $content).html(html); 
         }); 
        }); 
       }); 
      }); 
     }); 
    }); 
}); 

每個Repository.Projects.*方法中包含的異步調用來獲取數據。傳入的函數是回調函數,它在成功時傳遞結果數據。 Repository使用泛型函數處理錯誤,所以我不需要傳入錯誤函數。我需要確保在xslt轉換之前調用了每個函數,並返回數據。

Repository.Projects.*所有的方法是這樣的

GetStages: function (successCallback) { 
    $.ajax({ 
     type: "POST", 
     contentType: "application/json; charset=utf-8", 
     url: "DataRepository.asmx/GetStages", 
     cache: false, 
     data: JSON.stringify({}), 
     dataType: "json", 
     success: successCallback, 
     error: Repository.FailureCallback 
    }); 
} 

好像我應該能夠改寫這個,我只是不明白怎麼樣。

回答

2

您希望Repository.Projects.*下的所有函數都返回$.ajax調用(該函數本身返回一個延遲實例)。

GetStages: function() { 
    return $.ajax(...); 
} 

然後你可以使用此代碼:

$.when(
    Repository.Projects.GetStages() 
    ,Repository.Projects.GetBenefits() 
    ,Repository.Projects.GetPriorities() 
    ,Repository.Projects.GetDifficulties() 
    ,Repository.Projects.GetFactors() 
    ,Repository.Projects.GetRatings() 
) 
    .then(done, fail) 
; 

// success function 
function done(stageResponse, benefitResponse, ...) { 
    /* 
    each param is the success callback from jquery.ajax.success 
    arguments are [ data, textStatus, jqXHR ] 
    */ 
    var 
    stageXML = $.parseXML(stageResponse[0].d) 
    ,benefitXML = $.parseXML(benefitResponse[0].d) 
    ... 
    ; 

    Repository.Projects.GetProjectRatings(...) 
} 

// error function 
function fail() { } 

編輯:

你可以通過包裝Repository.Projects.*用自己的遞延對象使這一清潔。

function extractResult($ajax) { 
    return $.Deferred(function(dfd) { 
    $ajax 
     .done(function(response) { 
     dfd.resolve(response.d); 
     }) 
     .fail(function(jqXhr) { 
     // pass stuff to the failed function 
     dfd.reject(...); 
     }) 
    ; 
    }).promise(); 
} 

請記住,較乾淨的實施將無法與上述代碼一起使用。成功功能只接收到需要傳遞給$.parseXML的內容。因此,您可以將完成的功能變量更改爲$.parseXML(stageResponse)

如果Repository.Projects.Get*功能唯一的作用是使$.ajax請求,我會完全擺脫它們。

性感方式:

$.when.apply($ 
    ,$.map([ 
    // these could be directly replaced with calls to $.ajax(...) 
    Repository.Projects.GetStages() 
    ,Repository.Projects.GetBenefits() 
    ,Repository.Projects.GetPriorities() 
    ,Repository.Projects.GetDifficulties() 
    ,Repository.Projects.GetFactors() 
    ,Repository.Projects.GetRatings() 
    ], exctractResult) 
) 
    .done(function(stageResponse, benefitResponse, ...) { 
    var 
     stageXML = $.parseXML(stageResponse) 
     ,benefitXML = $.parseXML(benefitResponse) 
     ... 
    ; 

    ... 
    }) 
;