Angular $q 多项承诺
Angular $q multiple promises
我正在尝试这样做:
- 运行 乐趣 1
- 然后在 fun1 returns(承诺解决)之后,运行 fun2 和 fun3 并行(异步)
- 然后在 fun2、3 return(承诺解决)之后,运行 一些具有不同输入的 fun4 全部并行
然后最终 运行 fun5 在所有 fun4 都被解析之后。
$q.all({
fun1: fun1()
}).then(function(){
return $q.all({
fun2: fun2(),
fun3: fun3(),
});
}).then(function(){
var promises = [];
for(var i = 0; i < 3; i += 1){
promises.push(fun4(i));
}
return $q.all(promises);
}).then(function(){
fun5();
});
fun 1~5都是api调用类似这种模式:
var funX = function(){
return $http({
method: 'GET',
url: '/someURL'
}).success(function(data, status, headers, config) {
return;
}).error(function(data, status, headers, config) {
return new Error();
});
};
我想确保它们 运行 按照我上面描述的顺序排列。看起来 fun4 没有等待 fun2 和 fun3 到 return,fun5 也没有等待所有 fun4 到 return。
正如我之前所说,可能发生的情况是您的某些 Promise
出现故障。防止 $http
Promise
失败的最佳方法是处理 .catch()
中的错误(不要使用 .success()
和 .error()
作为它们已被弃用)和 return 一个 truthy 值。
以下是一个试图模拟您的进程失败的测试用例(打开控制台并查看记录的内容):
angular.module('Test', [])
.controller('Ctrl', function($q, Factory) {
$q.all({
fun1: Factory.succeedFunc('1')
})
.then(function() {
return $q.all({
fun2: Factory.failingFunc('2'),
fun3: Factory.succeedFunc('3')
});
})
.then(function() {
var promises = [];
for (var i = 0; i < 3; i++) {
promises.push(Math.random() > 0.5 ? Factory.failingFunc('4: ' + i) : Factory.succeedFunc('4: ' + i));
}
return $q.all(promises);
})
.then(function() {
Factory.succeedFunc('5');
});
})
.factory('Factory', function($q, $timeout) {
return {
failingFunc: function(msg) {
var deferred = $q.defer();
console.log('executing', msg);
$timeout(function() {
console.log('failed', msg);
deferred.reject();
}, 500);
return deferred.promise;
},
succeedFunc: function(msg) {
var deferred = $q.defer();
console.log('executing', msg);
$timeout(function() {
console.log('succeeded', msg);
deferred.resolve();
}, 1000);
return deferred.promise;
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="Test" ng-controller="Ctrl">
</div>
这是当你处理拒绝和 return Promise
s' .catch()
中的值时发生的情况(尽管要小心不要将 .catch()
因为这也会拒绝新创建的 Promise
:
angular.module('Test', [])
.controller('Ctrl', function($q, IgnoreErrors) {
var Factory = IgnoreErrors;
$q.all({
fun1: Factory.succeedFunc('1')
})
.then(function() {
return $q.all({
fun2: Factory.failingFunc('2'),
fun3: Factory.succeedFunc('3')
});
})
.then(function() {
var promises = [];
for (var i = 0; i < 3; i++) {
promises.push(Math.random() > 0.5 ? Factory.failingFunc('4: ' + i) : Factory.succeedFunc('4: ' + i));
}
return $q.all(promises);
})
.then(function() {
Factory.succeedFunc('5');
});
})
.factory('Factory', function($q, $timeout) {
return {
failingFunc: function(msg) {
var deferred = $q.defer();
console.log('executing', msg);
$timeout(function() {
console.log('failed', msg);
deferred.reject();
}, 500);
return deferred.promise;
},
succeedFunc: function(msg) {
var deferred = $q.defer();
console.log('executing', msg);
$timeout(function() {
console.log('succeeded', msg);
deferred.resolve();
}, 1000);
return deferred.promise;
}
};
})
.factory('IgnoreErrors', function(Factory) {
return {
failingFunc: function(msg) {
return Factory.failingFunc(msg).catch(function() {
return true;
});
},
succeedFunc: function(msg) {
return Factory.succeedFunc(msg).catch(function() {
return true;
});
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="Test" ng-controller="Ctrl">
</div>
所以我能够通过使用新的 api 解决这个问题并摆脱弃用的 error
和 success
.
我正在尝试这样做:
- 运行 乐趣 1
- 然后在 fun1 returns(承诺解决)之后,运行 fun2 和 fun3 并行(异步)
- 然后在 fun2、3 return(承诺解决)之后,运行 一些具有不同输入的 fun4 全部并行
然后最终 运行 fun5 在所有 fun4 都被解析之后。
$q.all({ fun1: fun1() }).then(function(){ return $q.all({ fun2: fun2(), fun3: fun3(), }); }).then(function(){ var promises = []; for(var i = 0; i < 3; i += 1){ promises.push(fun4(i)); } return $q.all(promises); }).then(function(){ fun5(); });
fun 1~5都是api调用类似这种模式:
var funX = function(){
return $http({
method: 'GET',
url: '/someURL'
}).success(function(data, status, headers, config) {
return;
}).error(function(data, status, headers, config) {
return new Error();
});
};
我想确保它们 运行 按照我上面描述的顺序排列。看起来 fun4 没有等待 fun2 和 fun3 到 return,fun5 也没有等待所有 fun4 到 return。
正如我之前所说,可能发生的情况是您的某些 Promise
出现故障。防止 $http
Promise
失败的最佳方法是处理 .catch()
中的错误(不要使用 .success()
和 .error()
作为它们已被弃用)和 return 一个 truthy 值。
以下是一个试图模拟您的进程失败的测试用例(打开控制台并查看记录的内容):
angular.module('Test', [])
.controller('Ctrl', function($q, Factory) {
$q.all({
fun1: Factory.succeedFunc('1')
})
.then(function() {
return $q.all({
fun2: Factory.failingFunc('2'),
fun3: Factory.succeedFunc('3')
});
})
.then(function() {
var promises = [];
for (var i = 0; i < 3; i++) {
promises.push(Math.random() > 0.5 ? Factory.failingFunc('4: ' + i) : Factory.succeedFunc('4: ' + i));
}
return $q.all(promises);
})
.then(function() {
Factory.succeedFunc('5');
});
})
.factory('Factory', function($q, $timeout) {
return {
failingFunc: function(msg) {
var deferred = $q.defer();
console.log('executing', msg);
$timeout(function() {
console.log('failed', msg);
deferred.reject();
}, 500);
return deferred.promise;
},
succeedFunc: function(msg) {
var deferred = $q.defer();
console.log('executing', msg);
$timeout(function() {
console.log('succeeded', msg);
deferred.resolve();
}, 1000);
return deferred.promise;
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="Test" ng-controller="Ctrl">
</div>
这是当你处理拒绝和 return Promise
s' .catch()
中的值时发生的情况(尽管要小心不要将 .catch()
因为这也会拒绝新创建的 Promise
:
angular.module('Test', [])
.controller('Ctrl', function($q, IgnoreErrors) {
var Factory = IgnoreErrors;
$q.all({
fun1: Factory.succeedFunc('1')
})
.then(function() {
return $q.all({
fun2: Factory.failingFunc('2'),
fun3: Factory.succeedFunc('3')
});
})
.then(function() {
var promises = [];
for (var i = 0; i < 3; i++) {
promises.push(Math.random() > 0.5 ? Factory.failingFunc('4: ' + i) : Factory.succeedFunc('4: ' + i));
}
return $q.all(promises);
})
.then(function() {
Factory.succeedFunc('5');
});
})
.factory('Factory', function($q, $timeout) {
return {
failingFunc: function(msg) {
var deferred = $q.defer();
console.log('executing', msg);
$timeout(function() {
console.log('failed', msg);
deferred.reject();
}, 500);
return deferred.promise;
},
succeedFunc: function(msg) {
var deferred = $q.defer();
console.log('executing', msg);
$timeout(function() {
console.log('succeeded', msg);
deferred.resolve();
}, 1000);
return deferred.promise;
}
};
})
.factory('IgnoreErrors', function(Factory) {
return {
failingFunc: function(msg) {
return Factory.failingFunc(msg).catch(function() {
return true;
});
},
succeedFunc: function(msg) {
return Factory.succeedFunc(msg).catch(function() {
return true;
});
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="Test" ng-controller="Ctrl">
</div>
所以我能够通过使用新的 api 解决这个问题并摆脱弃用的 error
和 success
.