我知道这个问题很老了,而且已经有一个很好的答案了,但是还有很多后续问题,我想整合一些答案,即使只是作为自己的参考。
$q.when返回一个Promise对象。要获取Promise的解决值,请使用promise .then(callbackFunction)
语法...
let i = 1;
$q.when(i).then(function(resolvedValue){
console.log(resolvedValue === i);
});
在这里了解更多 关于 Promises 的信息
当你传递的不是 Promise/"then-able",比如整数、字符串、数组、对象甚至函数时,其行为相同。以下是一些例子:
let o = {name:'Nate'};
$q.when(o).then(function(resolvedValue){
console.log(resolvedValue === o);
});
let a = ['Nate'];
$q.when(a).then(function(resolvedValue){
console.log(resolvedValue === a);
});
如果您传递一个未执行的函数,它就像传递任何其他对象一样,除了 Promise;resolvedValue 将等于函数本身,而不管函数的返回值如何。
let i = 1;
let f = function(){ return Promise.resolve(i); };
$q.when(f).then(function(resolvedValue){
console.log(resolvedValue === f);
console.log(resolvedValue !== i);
});
先调用函数 $q.when(func)
与 $q.when(func())
正如@jrista所说,如果你有一个返回 Promise 的函数,并且在将其传递给 $q.when
之前调用该函数,那么你实际上只是将一个 Promise 传递到了 $q.when
中。
let i = 1;
let f = function(){ return i; };
$q.when(f);
$q.when(f());
$q.when(func)
vs $q.when(..).then(func)
注意不要混淆将函数传递到Promise / $q.when(f)中的情况(在这种情况下,Promise的解析值将等于该函数):
let f = function(){ };
$q.when(f)
与使用 .then()
中的函数相比(在这种情况下,该函数将被执行并传递 Promise 的已解决值):
let f = function(){ };
$q.when().then(f);
如果我传递一个 Promise/"then-able" 会怎样?
正如文档和其他答案所述,传递一个 Promise 对象或任何“then-able”是特殊的。与其解析为相同的 Promise 对象,$q.when
将解析为 Promise 的已解决值。
let i = 1;
let p = Promise.resolve(i);
$q.when(p).then(function(resolvedValue){
console.log(resolvedValue !== p);
console.log(resolvedValue === i);
});
为什么要使用$q.when
?
正如文档所述:
当你处理一个可能是或可能不是promise的对象,或者promise来自于一个不可信的来源时,它非常有用。
一致的返回类型
让我们举个“可能是或可能不是promise的对象”的例子;也许您缓存了$http()
的结果。现在,您可以编写一个函数,该函数返回缓存的值,或者返回异步的$http()
请求以获取该值。
var cache = {};
var get_value_from_cache_or_$http_get = function (resource_id){
var cached_value = cache[resource_id];
if (cached_value){
return $q.when(cached_value);
} else {
return $http.get(resource_id);
}
}
现在函数get_value_from_cache_or_$http_get
将始终返回一个"then-able",无论它是否获取了一个promise(即$http.get
),或者可能是一个不是promise的值(即从cache
中获取,但包装在$q.when
中)
$scope
在UI中的更新
我认为文档中的这部分特别重要(也许是我使用$q.when
的最重要原因)...
$q
与AngularJS中的$rootScope.Scope
Scope模型观察机制集成,这意味着更快地将解析或拒绝传播到您的模型中,并避免不必要的浏览器重绘,从而导致UI闪烁。
换句话说,我发现当我获取一个普通 Promise 的解析值并分配给 $scope 时,我不总是立即在 UI 中看到变化(我必须等待下一个 $digest())。
let p = Promise.resolve('update');
p.then(function(resolvedValue){ $scope.val = resolvedValue; })
如果我
将Promise包装在$q.when
中,则一旦解析的值被分配给
$scope
,我就会立即看到UI中的更改。
let p = Promise.resolve('update');
$q.when(p).then(function(resolvedValue){ $scope.val = resolvedValue; })
$q.when
与 $q.resolve
注意这两个函数是相同的:$q.when === $q.resolve
,正如文档所说:
[$q.resolve
是] when
的别名,以保持与 ES6 命名一致。