使用jQuery的延迟

时间:2011-12-20 20:07:19

标签: jquery-deferred

我一直在阅读关于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
    });
}

似乎我应该能够重写这个,我只是看不出来。

1 个答案:

答案 0 :(得分: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)
       ...
     ;

     ...
   })
 ;