angular $q, for-loop 내 및 후에 여러 약속을 연결하는 방법
반복할 때마다 비동기 함수를 호출하는 for-loop을 원합니다.
for-loop 후에 다른 코드블록을 실행하고 싶은데 for-loop 내의 이전 콜이 모두 해결될 때까지는 실행하지 않습니다.
현시점에서의 문제는 for-loop 후의 코드 블록이 모든 비동기 콜이 종료되기 전에 실행되거나 전혀 실행되지 않는 것입니다.
FOR-루프가 있는 코드 부분과 그 뒤의 코드 블록(전체 코드는 바이올린 참조):
[..]
function outerFunction($q, $scope) {
var defer = $q.defer();
readSome($q,$scope).then(function() {
var promise = writeSome($q, $scope.testArray[0])
for (var i=1; i < $scope.testArray.length; i++) {
promise = promise.then(
angular.bind(null, writeSome, $q, $scope.testArray[i])
);
}
// this must not be called before all calls in for-loop have finished
promise = promise.then(function() {
return writeSome($q, "finish").then(function() {
console.log("resolve");
// resolving here after everything has been done, yey!
defer.resolve();
});
});
});
return defer.promise;
}
jsFiddle을 작성했습니다.이거는 http://jsfiddle.net/riemersebastian/B43u6/3/에 있습니다.
현시점에서는 실행 순서는 정상인 것 같습니다(콘솔 출력 참조).
이는 단순히 모든 함수 호출이 실제 작업을 수행하지 않고 즉시 반환되기 때문이라고 추측합니다.setTimeout을 사용하여 defer.resolve를 지연시키려고 했지만 실패했습니다(마지막 코드 블록은 실행되지 않았습니다).바이올린의 외설 블록에서 볼 수 있습니다.
파일에 쓰고 파일에서 읽는 실제 기능을 사용하면 마지막 쓰기 작업이 끝나기 전에 마지막 코드 블록이 실행되는데, 이것은 내가 원하는 것이 아니다.
물론 읽기/쓰기 기능 중 하나일 수도 있지만, 여기에 게재한 코드에 이상이 없음을 확인하고 싶습니다.
필요한 것은 $q.입니다.이것은 많은 약속을 하나로 묶은 것입니다.이것은 모든 약속이 해결되었을 때만 해결됩니다.
이 경우 다음과 같은 작업을 수행할 수 있습니다.
function outerFunction() {
var defer = $q.defer();
var promises = [];
function lastTask(){
writeSome('finish').then( function(){
defer.resolve();
});
}
angular.forEach( $scope.testArray, function(value){
promises.push(writeSome(value));
});
$q.all(promises).then(lastTask);
return defer.promise;
}
새로운 ES7을 사용하면 훨씬 더 간단한 방법으로 동일한 결과를 얻을 수 있습니다.
let promises = angular.forEach( $scope.testArray, function(value){
writeSome(value);
});
let results = await Promise.all(promises);
console.log(results);
사용할 수 있습니다.$q
그리고 약속을 묶기 위해 함께 '연결'을 합니다.
function setAutoJoin() {
var deferred = $q.defer(), data;
var array = _.map(data, function(g){
return g.id;
});
function waitTillAllCalls(arr) {
return arr.reduce(function(deferred, email) {
return somePromisingFnWhichReturnsDeferredPromise(email);
}, deferred.resolve('done'));
}
waitTillAllCalls(array);
return deferred.promise;
}
이것은 ES5 구문을 사용하여 동작했습니다.
function outerFunction(bookings) {
var allDeferred = $q.defer();
var promises = [];
lodash.map(bookings, function(booking) {
var deferred = $q.defer();
var query = {
_id: booking.product[0].id,
populate: true
}
Stamplay.Object("product").get(query)
.then(function(res) {
booking.product[0] = res.data[0];
deferred.resolve(booking)
})
.catch(function(err) {
console.error(err);
deferred.reject(err);
});
promises.push(deferred.promise);
});
$q.all(promises)
.then(function(results) { allDeferred.resolve(results) })
.catch(function(err) { allDeferred.reject(results) });
return allDeferred.promise;
}
언급URL : https://stackoverflow.com/questions/21024411/angular-q-how-to-chain-multiple-promises-within-and-after-a-for-loop
'programing' 카테고리의 다른 글
AJAX 게시 오류: 안전하지 않은 헤더 "연결" 설정을 거부했습니다. (0) | 2023.02.25 |
---|---|
ngModel의 차이점은 무엇입니까?$modelValue 및 ngModel.$viewValue 값 (0) | 2023.02.25 |
React.js를 사용하여 클래스를 추가하려면 어떻게 해야 합니까? (0) | 2023.02.25 |
어떤 것을 사용할까, 앵글UI 부트스트랩 또는 AngularStrap? (0) | 2023.02.25 |
화살표 기능 및 괄호(), {} 또는 {} 사용 (0) | 2023.02.25 |