0

我一直在阅读有关 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.*方法都包含一个异步调用来获取数据。传入的函数是回调,它会在成功时传递结果数据。存储库使用通用函数处理错误,因此我不需要传入错误函数。我需要确保在 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
    });
}

看来我应该能够重写这个,我只是看不到如何。

4

1 回答 1

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。所以你可以将 done 函数变量更改为$.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)
       ...
     ;

     ...
   })
 ;
于 2012-03-08T14:04:20.620 回答