Угловой обещает последовательный цикл
У меня есть следующий набор данных.
$scope.orders = [
{ material: 'A', quantity: 32, orderNumber: 'dummy'},
{ material: 'A', quantity: 65, orderNumber: 'dummy'},
{ material: 'A', quantity: 86, orderNumber: 'dummy'},
{ material: 'B', quantity: 45, orderNumber: 'dummy'},
{ material: 'B', quantity: 68, orderNumber: 'dummy'},
{ material: 'B', quantity: 15, orderNumber: 'dummy'},
{ material: 'C', quantity: 11, orderNumber: 'dummy'}
];
Я хочу обработать (createOrder) заказы, сгруппированные по материалу. После обработки всех заказов на этот конкретный материал я хочу вызвать другую функцию (materialRun), которая выполняет запуск материала. После того, как эта функция выполнена успешно, следующий материал (с соответствующими заказами) должен быть обработан и т. д.. Все эти вызовы должны быть последовательными, потому что серверная часть не может обрабатывать все параллельно.
Итак, я ищем что-то вроде этого:
Материал а: заказ 1 - > заказ 2 - > заказ 3 - > материалран
Когда материал из A будет готов, начните материал B
B материал: приказ 1 -приказ 2 -приказ 3 -> materialRun
Когда материал из B будет завершен, начните материал C
...
Мне также нужен результат от каждого createOrder для обновления списка заказов
Сейчас я использую угловые обещания, но я открыт для предложений. Я надеюсь, что эта скрипка помощь: http://jsfiddle.net/a1sp0ye2/
2 ответа:
Ниже приведен шаблон для циклов с асинхронными телами, то есть следующая итерация должна иметь место только тогда, когда асинхронная задача завершена. Он работает для обещаний в угловом контексте, но может быть обобщен для любой реализации обещаний, которую я считаю:
/** * Loop the items array asynchronously. * * @param items - Array to iterate * @param doLoopBody - Callback that executes the body loop, returns promise */ function asyncLoop(items, doLoopBody) { var i = 0, d = $q.defer(); nextIteration(); return d.promise; function nextIteration() { if( i < items.length ) { doLoopBody(items[i], i, items).then( function() { i++; nextIteration(); }, onError ); } else { d.resolve(); } } function onError(reason) { d.reject(reason); } }
Исходя из этого, здесь является грубой реализацией вашего случая (смотрите консоль браузера для вывода).
Я не уверен, что это может вам помочь, но попробуйте использовать мой код: jsfiddle
$scope.promises = []; ordersByMaterial.forEach(function(order) { $scope.promises.push(createOrder(order)); });
Я попытался проверить его, создав
$scope.logsCreateValue = [];
, где я храню случайные значения изMath.floor(Math.random() * 10);
смотрите вconsole.log($scope.logsCreateValue);
, он должен совпадать со значениями из$scope.orders[key].orderNumber = res[key].orderNumber;