【问题标题】:Recursive Ajax deferred object递归 Ajax 延迟对象
【发布时间】:2014-02-08 17:57:46
【问题描述】:

当递归 ajax 函数结束其递归时,我需要在 DOM 中粘贴一些数据。

我遇到的问题是“$.when().done()”将在递归的第一步触发,但我需要它在递归的最后一步触发,当递归结束时。

我真的不知道如何实现它,任何帮助将不胜感激!

function recursiveFunction(data) {

    // do something with data
    // and remove elements processed from data

    var param = {
            "data" : data
    };
    return $.ajax({
            data:  param,
            url:   'script.php',
            type:  'post',
            success:  function(response) {
                recursiveFunction(response);
            },
    });
}

$.when(recursiveFunction(data)).done(function(response){
    paintData();
});

【问题讨论】:

    标签: jquery ajax deferred


    【解决方案1】:

    您可以使用deffered.promise 对象来处理递归执行。我已经修改了您的示例以提供一些数据和停止条件。此处示例 -> jsfiddle

    【讨论】:

      【解决方案2】:

      简明扼要(并且可以说是简单)的关键是:

      • 为您的数据使用外部成员,而不是尝试通过它

      • 在递归中构建.then()链,使用成功路径进行递归,失败路径为终止条件

      • 保证php脚本最终会返回HTTP错误,从而避免无限递归。

      递归函数:

      function recursiveFunction(response) {
          if(response) {
              // use `response` to act on the outer object `data`
          }
          return $.ajax({
              url:   'script.php',
              type:  'post',
              data:  {
                  "data" : data
              }
          }).then(recursiveFunction);
      }
      

      调用如下:

      var data = {'whatever':'whatever'};//this is the outer member
      recursiveFunction().fail(paintData);
      

      没有.when(),也没有乱七八糟的计数器。

      参见 FIDDLE,为了演示,它使用 setTimeout 代替 $.ajax(),并使用数组作为外部成员。

      【讨论】:

      • 我需要 .when() 因为我在等待 2 个延迟对象
      • 不,.when() 用于解决两个或多个 parallel 承诺。你有两个 sequential 承诺。你的第二个.ajax() 是在第一个成功之后创建的。
      • 太棒了,我一直在寻找一个功能与您描述的一样:sequential Ajax 调用。我正在搜索一个非常大的数据库(数百万行),发现我可以通过分块请求来改善用户体验和加载时间。这导致 N / nN:总行数,n:每个块的行数) ajax 调用。如果将并行发送调用,则这将与对 N 行的一个请求相同——击败解决方法。谢谢甜菜根-甜菜根!
      • @Beetroot-Beetroot 请参阅我的post,了解我在实现上述功能时遇到的问题。
      【解决方案3】:

      如果你打算使用打字稿,你可以这样做

          private updateDataNextLink(nextLinkAddress: string, outputAddress: string, defer?: JQueryDeferred<any>): JQueryPromise<string> {            
              if (defer){
                  defer = $.Deferred();           
              }
      
              DataService.retrieveSkipTokenData1(nextLinkAddress).done((tagData) => {
                  let tableData: any = ServiceContainer.officeApiHelper.createExcelTableFormat(tagData);
                  ServiceContainer.officeApi.addData(outputAddress, [], tableData.rows).done((address) => {
                      if (tagData['odata.nextLink']) {
                          ServiceContainer.officeApi.getOffsetCell(tableData.rows.length, 0, address).done((offsetAddress) => {
                              App.Instance.updateDataNextLink(tagData['odata.nextLink'], offsetAddress, defer);
                          });
                      } else {
                          defer.resolve(address);
                      };
                  });
              });
      
              return defer.promise();
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多