2016-04-21 40 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)