TL;DR:是的,只需从同步方法返回正常值并将它们$q.all
用作输入参数。它将正确处理它们。
长答案
如果我们查看角度代码,$q.all
我们会在这一行看到输入参数是如何处理的:
function all(promises) {
....
forEach(promises, function(promise, key) {
....
ref(promise).then(function(value) {
所以每个参数都被传递给在这一行定义ref
的函数。接受一个参数,如果它是一个承诺,它会返回它ref
if (value && isFunction(value.then)) return value;
如果不是,则该值将用一个新创建的承诺包装,该承诺将被返回。该承诺会尽快得到解决,但不会在此事件循环迭代中解决。
return {
then: function(callback) {
var result = defer();
nextTick(function() {
result.resolve(callback(value));
});
return result.promise;
}
};
这意味着您可以安全地从同步方法中返回非承诺值。
function asyncFirst() {
var def = $q.defer();
$timeout(function(){
$scope.first = true;
def.resolve();
}, 1000);
return def.promise;
}
function syncSecond() {
$scope.second = true;
return {
data1: 'abc',
data2: 123
};
}
$q.all([
asyncFirst(),
syncSecond()
])
.then(function(){
$scope.all = true;
});
在这个 jsbin 示例中查看它的实际效果
$q.when
编辑:正如用户@Bergi 建议的那样,如果需要使用源,任何常规值都可以转换为承诺但是,$q.when
使用该ref
函数将值转换为承诺并在下一次事件循环迭代中解决承诺。严格来说,该方法本身是同步的,因为它没有延迟地返回。但是结果会立即包装到 Promise 中,并且在下一次事件循环迭代之前不会被使用。这意味着不使用同步方法。至少不是在大多数人想象的同步方法中。的总体结果$q.all
将使用异步等同步方法,但在下一次迭代中解决。考虑这个警告。