2016-02-24 59 views
0

我有JavaScript函数,工作非常顺利,直到我需要(在这种情况下jQuery.ajax)开始使用异步函数的递归复杂。我在下面列出了一些伪码,给出了情况的要点。我想用promise(而不是当前的回调函数)来实现这个代码,但是不能解决如何处理递归和多个有条件的ajax调用。如果我正确理解承诺,他们允许您按异步调用返回,但我如何处理下面的情况?多个条件异步递归函数和jQuery承诺

function wrapperFunction(success,error) { 
    var level = 0; 
    result = []; 

    var innerFunction = function(info,result,success,error) { 
     level++; 

     jQuery.ajax({ 
      url: 'baseurl1' + info, 
      success: parseData, 
      error: error 
     }); 

     function parseData(data) { 
      data.forEach(function(item) { 
       result.push(item.something); 

       if (item.info) { 
        innerFunction(item.info, result, success, error); 
       } 
      }); 

      if (data.condition) { 
       jQuery.ajax({ 
        url: 'baseurl2' + info, 
        success: parseData2, 
        error: error 
       }); 
      } 

      function parseData2(data2) { 
       data2.forEach(function(item2) { 
        if (item2.condition) { 
         jQuery.ajax({ 
          url: 'baseurl3' + info, 
          success: parseData3, 
          error: error 
         }); 
        } 
       }); 
       function parseData3(data3) { 
        if (data3.condition) { 
         jQuery.ajax({ 
          url: 'baseurl4' + info, 
          success: parseData4, 
          error: error 
         }); 
        } 
        function parseData4(data) { 
         result.push(data2.something + data4.something); 
        } 
       } 
      } 

      level--; 
      if (level == 0 && success) { 
       success(result); 
      } 
     } 

    } 

    innerFunction('rootinfo', result, success, error); 
} 

wrapperFunction(
    function(data) { 
     // process success 
    }, 
    function(err) { 
     // handle errors 
    } 
} 

正如我所说,这只是伪代码。我最初从我的真实代码中提取它,看看我是否可以在实际结构中找到自己的头。我知道它是有效的,如果ajax调用同步,但现在它们是异步的,它只有时有效(取决于调用返回的速度)。

如何使用承诺实现这种情况?

编辑

我刚刚制定了如何使用承诺连载一切,尽管这是一种方式,以等待一切结束我宁愿并行运行多个呼叫,然后找到一个方法来等待一切都完成了。我知道这是可能的承诺,但我不知道如何。

+0

为什么要使用承诺?他们对你现在拥有的东西没有真正的好处。还要注意这里没有递归。你也许可以整理代码使其更加优雅,但这取决于每个函数所需的范围以及它检索的数据。 –

+0

InnerFunction调用ajax查询,该查询在成功时调用parseData,该函数在特定条件下调用innerFunction。这看起来像递归给我。 –

+0

你可以做这样的事情:https://jsfiddle.net/sandenay/0pa0L9dx/ –

回答

0

我有它的工作,与桑迪普纳亚克的帮助下(见上述评论)。我以为我发布了一个类似问题的任何人遇到这个帖子的工作版本的伪代码。

我已经基本上所有加入的承诺(内部和外部),其中如果所有的内部承诺得到解决外承诺不会得到解决的两个层次。整理代码可能有一定的空间,但它仍然可以工作。

function wrapperFunction(success,error) { 
    var level = 0; 
    var result = []; 
    var outerPromises = []; 

    var innerFunction = function(info,result,success,error) { 
     var outerPromise = new jQuery.Deferred(); 
     outerPromises.push(outerPromise); 

     level++; 

     jQuery.ajax({ 
      url: 'baseurl1' + info, 
      success: parseData, 
      error: error 
     }); 

     function parseData(data) { 
      data.forEach(function(item) { 
       result.push(item.something); 

       if (item.info) { 
        innerFunction(item.info, result, success, error); 
       } 
      }); 

      if (data.condition) { 
       jQuery.ajax({ 
        url: 'baseurl2' + info, 
        success: parseData2, 
        error: error 
       }); 
      } else { 
       outerPromise.resolve(); 
      } 

      function parseData2(data2) { 
       var innerPromises = []; 

       data2.forEach(function(item2) { 
        var innerPromise = new jQuery.Deferred(); 
        innerPromises.push(innerPromise); 

        if (item2.condition) { 
         jQuery.ajax({ 
          url: 'baseurl3' + info, 
          success: parseData3, 
          error: error 
         }); 
        } else { 
         innerPromise.resolve(); 
        } 

        function parseData3(data3) { 
         if (data3.condition) { 
          jQuery.ajax({ 
           url: 'baseurl4' + info, 
           success: parseData4, 
           error: error 
          }); 
         } else { 
          innerPromise.resolve(); 
         } 
         function parseData4(data) { 
          result.push(data2.something + data4.something); 

          innerPromise.resolve(); 
         } 
        } 
       }); 

       jQuery.when.apply(undefined, innerPromises).then(function() { outerPromise.resolve(); }); 
      } 

      level--; 
      if (level == 0 && success) { 
       jQuery.when.apply(undefined, outerPromises).then(function() { success(result); }); 
      } 
     } 

    } 

    innerFunction('rootinfo', result, success, error); 
} 

wrapperFunction(
    function(data) { 
     // process success 
    }, 
    function(err) { 
     // handle errors 
    } 
}