2016-01-09 2 views
1

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

У меня есть асинхронный запрос к базе данных, которая возвращает массив данных. Для каждого объекта в этом массиве мне нужно запустить другой запрос async в базу данных, и как только ВСЕ эти запросы async будут разрешены, я хочу вернуть их. Я читал, что ты мог бы сделать это с $ q.all (...)

Так вот код:

Factory.firstAsyncRequest(id).then(function (arrayWithObjects) { 
var promises = []; 
var dataArr = []; 
    angular.forEach(arrayWithObjects, function (object, key) { 
    var deferred = $q.defer(); 
    promises.push(deferred); 
    Factory.otherAsyncRequest(key).then(function (objectData) { 
     dataArr.push({ 
      name: objectData.name, 
      key: key, 
      status: objectData.status 
     }); 
     deferred.resolve(); 
     console.info('Object ' + key + ' resolved'); 
    }); 
    }); 
    $q.all(promises).then(function() { 
    $rootScope.data = dataArr; 
    console.info('All resolved'); 
    });}); 

Из консоли я вижу, что $ q.all разрешен перед каждым объектом. У меня что-то не так? Это похоже на работу для всех ...

Ваша помощь высоко ценится, Искал всю ночь, это 5:30 теперь я лол ..

Приветствия

EDIT: Так что для тех, кто приходит здесь позже: это был просто обещание.push (отложенный.PROMISE) бит. Tho, я читал, что anguar.forEach на самом деле не рекомендуемый метод для цикла через массив, потому что он изначально не был сконструирован для использования конечным пользователем. Не знаю, если это правильно, но я понял, еще один способ, если вы не хотите использовать angular.forEach:

Users.getAll(uid).then(function (users) { 
      var uids = ObjHandler.getKeys(users); //own function just iterating through Object.keys and pushing them to the array 
      var cntr = 0; 
      function next() { 
      if (cntr < uids.length) { 
       Users.getProfile(uids[cntr]).then(function (profile) { 
       var Profile = { 
        name: profile.name, 
        key: uids[cntr], 
        status: profile.status 
       }); 
       dataArr[uids[cntr]] = Profile; 
       if(cntr===uids.length-1) { 
        defer.resolve(); 
        console.info('Service: query finished'); 
       } else {cntr++;next} 
       }); 
      } 
      } 
      next(); 
     }); 

и функция GETKEY:

.factory('ObjHandler', [ 
function() { 
    return { 
    getKeys: function(obj) { 
     var r = []; 
     for (var k in obj) { 
     if (!obj.hasOwnProperty(k)) 
      continue; 
     r.push(k) 
     } 
     return r 
    } 
    }; 
}]) 
+0

это 5:40 утра до меня;) –

+0

Решите данные, не нажимайте их на массив; то он будет доступен внутри обратного вызова. '$ q.all' разрешает массив результатов. – elclanrs

+0

@elclanrs: Обычно я это делаю, но на самом деле я не толкаю данные в массив, а вручную определяю ключи «dataArr [key] = objectData». Не могли бы вы сделать это решительно, не так ли? –

ответ

1

Вместо

promises.push(deferred); 

Попробуйте это:

promises.push(deferred.promise); 
+0

ЭТО было! Darrrnn. Огромное спасибо! –

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