2016-01-07 2 views
1

Я пытаюсь написать цикл, который выполняет множество HTTP-запросов и добавляет каждый ответ в список.Angular - для Loop HTTP Callback/Promise

Однако, я не думаю, что я собираюсь сделать это совершенно правильно.

Я думаю, что я не выполняю требуемые обещания правильно. Журнал консоли после цикла for показывает массив myList как пустой.

Код:

var _myList = [] 

function getStuff() { 

    var deferred = $q.defer() 

    var url = someUrl 

    $http.get(url).success(function(response) { 

     if (response.array.length > 0) { 

      // loop starts here 
      for (var i=0; i < response.array.length; i++) { 

       getThing(response.array[i].id); 

      }; 
      // check the varibale here 

      console.log(_myList); 

      deferred.resolve('Finished'); 

     } else { 

      deferred.resolve('No stuff exists'); 

     }; 

    }).error(function(error) { 

     deferred.reject(error); 

    }); 

    return deferred.promise; 

}; 

function getThing(thindId) { 

    var deferred = $q.defer() 

    var url = someUrl + thingId; 

     $http.get(url).success(function(response) { 

      _myList.push(response); 

      deferred.resolve(response); 

     }).error(function(error) { 

      deferred.reject(error); 

     });  

    return deferred.promise; 

}; 
+0

[Это] (http://stackoverflow.com/questions/13951456/using-offferred-with-nested-ajax-calls-in-a-loop) выглядит многообещающим, просто конвертируйте $ .ajax в $ http –

+0

Имеет ли значение, выполняются ли они параллельно или вы хотите, чтобы они выполнялись последовательно ? – jusopi

ответ

1

Вы можете упростить код следующим образом:

var allThings = response.array.map(function(id){ 
    var singleThingPromise = getThing(id); 
    //return a single request promise 
    return singleThingPromise.then(function(){ 
    //a getThing just ended inspect list 
    console.log(_myList); 
    }) 
}); 
$q.all(allThings).then(function(){ 
    //only resolve when all things where resolved 
    deferred.resolve('Finished'); 
}, function(e){ 
    deferred.reject('Something went wrong ' + e); 
}); 
+0

Работал отлично, спасибо. – user2085143

1

Вы действительно не сможете заполнить _myList массив с для цикла, как вы создали. Вместо этого создайте массив обещаний - по одному на элемент данных в response.array и верните его как внутреннее обещание.

function getStuff() { 

    var url = someUrl; 

    return $http.get(url).then(function(response) { 
     if (response.data.array.length > 0) { 
      return $q.all(response.data.array.map(function(data) { 
       return getThing(data.id); 
      })); 
     } else { 
      return 'No stuff exists'; 
     } 
    }); 
} 

function getThing(thindId) { 
    var url = someUrl + thingId; 
    return $http.get(url).then(function(response) { 
     return response.data; 
    }); 
} 

После этого вы будете использовать getStuff так:

getStuff().then(function(myList) { 
    console.log(myList); 
}); 
+0

Это выглядит великолепно, не получится попробовать до завтра, сообщит вам, как это происходит. Быстрый вопрос; is 'return' в этом случае используется вместо offferred.resolve()? – user2085143

+0

Вы не должны использовать отложенные для этого. $ http-методы уже дают обещание, поэтому отложенный избыток (отложенный анти-шаблон). 'return' от обещания создает новое обещание быть переданным по цепочке. – dfsq