2016-04-21 64 views
0

我试图创建递归异步调用一个JSON输出(树形结构),并想出了下面 -异步递归。电话 - AngularJS

$scope.processTree = function (mData, callback) {    
      _processTree.getWebCollection(mData.url).then(
       function(_rdata){ 
         // transform xml -> json    
         var x2js = new X2JS(); 
         var json = x2js.xml_str2json(_rdata); 
         //console.log("XML DATA: " + _rdata); 
         //console.log("JSON DATA: " + JSON.stringify(json)); 
         var _webs = json.Envelope.Body.GetWebCollectionResponse.GetWebCollectionResult.Webs.Web; 

         // if response has [] of webs - array of objects/sites 
         if ($(_webs).length > 0 && $.isArray(_webs)) {         
          $.each(_webs, function (key) { 
           // loop and build tree 
           mData.children.push({           
            name: "Site: " + _webs[key]._Title, 
            url: _webs[key]._Url, 
            children: [] 
           });          
           // recursive loop call for each site again 
            $scope.processTree(mData.children[key]);           
          });        
         } 
         // if response has {} of webs - single object/site      
         else if ($.isPlainObject(_webs)) {         
           mData.children.push({           
            name: _webs._Title, 
            url: _webs._Url, 
            children: [] 
           });        
         } 
         // if no response or response is null, do nothing 
         else { 

         } 
       }, function(msg){      
        alert("ERROR!!! \n\nERROR DATA: " + msg[0] + " \tStatus: " + msg[1]); 
       });     
    }; 

function callback(mData){ 
    // do something - use mData, create tree html and display 
} 

递归得到所有的网站和子网站,如有每个站点并存储在一个变量 - mData中,完成后,我需要返回并使用此变量作为JSON输入来创建一个树形图。每个异步。调用返回一组网站或单个站点(如果有的话)。

如何才能返回mData,只有在整个递归完成后?如何知道递归是否已结束,并可以调用所需的函数?

回答

0

假设foo.getStuff(url)返回一个角度承诺,您可以使用类似于以下使用承诺和角的$q服务的模式。

function getRec(url) { 
    return foo.getStuff(url).then(function(data){ 
     var result = {} // construct your result 
     var promises = [] // array of promises for recursive calls. 
     for (x in data) { 
      promises.push(getRec(url).then(function(r){ 
       // update result with r 
      })) 
     } 
     // wait for all recursive calls and then resolve the promise with the constructed result 
     return $q.all(promises).then(function(){return result}) 
    }) 
} 

getRec(ROOT_URL).then(callback)