2015-09-20 3 views
0

Я делаю запрос GET на конечной точке с разбивкой по страницам, поэтому я делаю один вызов, выясняя, сколько страниц имеет конечная точка, затем перебирает каждую страницу, нажимая ответ данные с каждой страницы в один массив.

Однако, поскольку звонок настолько велик, когда мы собираем данные фабрики с моего контроллера, мне нужно поставить тайм-аут на мою функцию, чтобы убедиться, что все данные вошли до того, как они будут использованы.

Я надеялся переключить это на обещание на моем заводе, что контроллер будет ждать, пока запрос не будет завершен. Но поскольку я просматриваю каждую страницу, то, как я обычно структурировал это, не работает. Как я могу переделать это, чтобы обещать дождаться полного цикла через страницы моей конечной точки, чтобы я мог удалить таймаут с моего контроллера?

Factory API запрос GET

var productsData = []; 
var pageNumber = 1; 
var getAllProducts = function(){ 
    var deferred = $q.defer(); 
    return $http.get('/api/scroll?page=' + pageNumber,{cache: true}) 
     .then(function(response) { 
      for (var i = response.data.results.length - 1; i >= 0; i--) { 
       productsData.push(response.data.results[i]); 
      }; 
      while (pageNumber <= response.data.pages) { 
       getAllProducts(); 
       pageNumber++; 
      } 
      deferred.resolve(productsData) 
      return deferred.promise; 
     }); 
}; 

Контроллер Функция

var filterProducts; 
    var getProducts = function(type, filter) { 
     productFactory.getAllProducts() 
     .then(function(products) { 
      $timeout(function(){ 
       var allProducts = products; 
       switch (type) { 
        case "category": 
         filterProducts = $filter('filter')(allProducts, { 
          custom: {category_code: filter} 
         }); 
         break; 
        case "color": 
         filterProducts = $filter('filter')(allProducts, { 
          custom: {color_code: filter} 
         }); 
         break; 
        case "season": 
         filterProducts = $filter('filter')(allProducts, { 
          custom: {season: filter} 
         }); 
         break; 
        default: 
         filterProducts = allProducts; 
       } 
       $rootScope.products = _.sortBy(filterProducts, function(product) { 
        return product.custom.sku; 
       }); 
      }, 1000); 
     }); 
    }; 
+0

Избегайте [отложенные антипаттерны] (http://stackoverflow.com/q/23803743/1048572)! – Bergi

ответ

2

Вы должны создать отложенный объект за пределами функции GET вызова и разрешить его только после того, как все запросы выполняются. Поэтому я думаю, что это может выглядеть как этого

var productsData = []; 
 
var pageNumber = 1; 
 
var deferred; 
 

 
function getAllProducts() { 
 
    deferred = $q.defer(); 
 

 
    _getPageProducts(pageNumber); 
 

 
return deferred.promise; 
 
} 
 
function _getPageProducts(pageNumber) { 
 
    $http.get('/api/scroll?page=' + pageNumber,{cache: true}) 
 
     .then(function(response) { 
 
      for (var i = response.data.results.length - 1; i >= 0; i--) { 
 
       productsData.push(response.data.results[i]); 
 
      }; 
 
      if (pageNumber < response.data.pages) { 
 
       pageNumber++; 
 
       _getPageProducts(pageNumber); 
 
      } else { 
 
       deferred.resolve(productsData) ; 
 
      } 
 
     }); 
 
}

+0

Удивительно - спасибо! –

+0

Избегайте [отложенного антипаттера] (http://stackoverflow.com/q/23803743/1048572)! – Bergi

+0

Также избегайте глобального состояния (в переменных 'отложенных',' pageNumber' и 'productsData')! – Bergi

Смежные вопросы