2015-03-20 4 views
6

Birden fazla api'nin her birinin üzerine dönen bir $ http araması üzerinde çalışıyorum ve tüm verileri bir nesnede döndürür. $ Http araması yapıldığında genellikle çözüme hazır sözüm var. Buna benzer:

function getAllData(api) { 
    return $http({ 
     method: 'GET', 
     url: '/api/' + api 
    }) 
    .then(sendResponseData) 
    .catch (sendGetVolunteerError); 
} 

mevcut işlev Her API üzerinde döngüler ve bir diziye API her nesne iter ve daha sonra genel bir dizi içine iter. Düzleştirilmesi gereken çok boyutlu bir diziyi döndüren bu işleyiş vardı.

Bunu bir sözle iade etmek istiyorum, ancak undefined döndürüyor. Şimdiye kadar elimde ne var? Buna yaklaşmanın daha iyi bir yolu var mı?

DataService:

function getSearchData() { 
    return { 
     loadDataFromUrls: function() { 
      var apiList = ["abo", "ser", "vol", "con", "giv", "blo", "par"]; 
      var deferred = $q.defer(); 
      var log = []; 
      angular.forEach(apiList, function (item, key) { 
       var logNew = []; 
       $http({ 
        method: 'GET', 
        url: '/api/' + item 
       }).then(function (response) { 
        angular.forEach(response.data, function (item, key) { 
         this.push(item); 
        }, logNew); 
        return logNew; 
       }); 
       this.push(logNew); 
      }, log); 
      $q.all(log).then(

      function (results) { 
       deferred.resolve(
       JSON.stringify(results)) 
      }, 

      function (errors) { 
       deferred.reject(errors); 
      }, 

      function (updates) { 
       deferred.update(updates); 
      }); 
      return deferred.promise; 
     } 
    }; 
}; 

Denetleyici: Sen $q (Kodunuzdaki böyle sözler çözülmezse) 'de vaat listesini eklemek gerekir

function getSearchData(){ 
    return dataService.getSearchData.loadDataFromUrls; 
} 

$scope.searchData = getSearchData(); 
+1

Ben burada neler olduğunu% 100 emin değilim - sen boş dizileri ('logNew') beklemek istediğiniz' log 'dizisine itmemek? Bunun yerine '$ http' iadesiyle '' sözünü '' zorlamıyor musunuz? –

cevap

16

$q.all ve map fonksiyonu burada gerekenler şunlardır:

function getSearchData() { 
    return { 
     // returns a promise for an object like: 
     // { abo: resultFromAbo, ser: resultFromSer, ... } 
     loadDataFromUrls: function() { 
      var apiList = ["abo", "ser", "vol", "con", "giv", "blo", "par"]; 

      return $q.all(apiList.map(function (item) { 
       return $http({ 
        method: 'GET', 
        url: '/api/' + item 
       }); 
      })) 
      .then(function (results) { 
       var resultObj = {}; 
       results.forEach(function (val, i) { 
        resultObj[apiList[i]] = val.data; 
       }); 
       return resultObj;   
      }); 
     } 
    }; 
} 
+0

Bazı nedenlerle denetleyicide undefined dönüyorum: function getSearchData() { return dataService.getSearchData.loadDataFromUrls; } console.log (getSearchData()); – byrdr

+0

@byrdr Bunun nedeni, getSearchData' nesnesinin bir özelliği olarak "loadDataFromUrls" ile bir nesne döndürmesidir, ancak 'getSearchData' özelliği olarak' loadDataFromUrls 'öğesine erişiyorsunuz. Try: 'function getSearchData() {return dataService.getSearchData(). LoadDataFromUrls; } file.log (getSearchData()); 'Bu, veri hizmetiniz ve getSearchData işleviniz arasında neden fazladan bir katmanınız olduğu sorusunu bırakıyor. – JLRishe

+0

Bu mantıklı, teşekkürler. Yukarıdaki kod şu anda işlevin kendisini kaydeder. – byrdr

0

, hangi bir $promise service

Örnek olduğunu :

var firstPromise = service1.getMethod1().$promise; 
var secondPromise = service2.getMethod2().$promise; 
$q.all([firstPromise, secondPromise]).then(function(dataList){ 
    // dataList[0] will be result of `firstPromise` 
    // dataList[1] will be result of `secondPromise` 
}); 
Eğer api aramaların keyfi bir dizi varsa
1

Böyle bir şey yapacağını:

function getSearchData(){ 
    var deferred = $q.defer(); 
    var noOfCalls = apiList.length; 
    var results = []; 
    var called = 0; 

    angular.forEach(apiList, function(item, key) { 
     $http.get(url).then(function(result){ 
      results.push(result); 
      called++; 
      if(called == noOfCalls){ 
       deferred.resolve(results); 
      }  
     }) 
    }); 

    return deferred.promise; 
} 

her API çağrısı bu şekilde

function search1(){ 
     return $http.get(search1Url).then(function(result){ 
      // do something to it 
      return result; 
     }); 
} 

function search2(){ 
     return $http.get(search2Url).then(function(result){ 
      // do something to it 
      return result; 
     }); 
} 

function search3(){ 
     return $http.get(search3Url).then(function(result){ 
      // do something to it 
      return result; 
     }); 
} 

function search4(){ 
     return $http.get(search4Url).then(function(result){ 
      // do something to it 
      return result; 
     }); 
} 

function getSearchResult(){ 

    return $q.all([search1(), search2(), search3(), search4()]).then(function(results){ 
     // OPTIONAL aggregate results before resolving 
     return results; 
    }); 
} 
yılında $ .tüm kullanmak onun daha iyi temsil biliyorum Ancak eğer
+0

Bunu mu demek istediniz: $ q.defer() '? – GregL

+0

[Ertelenmiş antipattern nedir ve nasıl önleyebilirim?] (Http://stackoverflow.com/questions/23803743/what-is-the-deferred-antipattern-and-how-do-i-avoid-it) – JLRishe

+0

evet .. benim hata lekelenme için teşekkür ederim :) –