我的项目中有一个预先存在的非Angular API库。它有一个.request
方法,它返回jQuery.Deferred promises。我创建了一个简单的Angular服务,它包装了.request
方法,将其结果转换为Angular $ q promise。它看起来像这样:
var module = angular.module('example.api', []);
module.factory('api', function(
$q,
$window
) {
function wrappedRequest() {
var result = $window.API.request.apply($window.API, arguments);
return $q.when(result);
};
return {
request: wrappedRequest
};
});
我想编写一个测试,确保此服务正常运行。它将提供一个带有$window
的模拟API
,其request
方法返回jQuery.Deferred promises。我需要确保生成的对象是Angular $ q promises。
如何确定对象是否是Angular $ q承诺?
对于这个问题中给出的例子,区分jQuery.Deferred promises和Angular $ q promises就足够了,但理想情况下我们可以识别Angular $ q promises。
答案 0 :(得分:9)
通常,更好的方法是将您拥有的任何对象投射到Angular承诺中。
吸收andables的概念是Promises / A +规范的一部分。大多数承诺库都有办法做到这一点。它允许在promise实现和统一API之间实现令人敬畏的互操作。
为此,$ q使用.when
:
将可能是值的对象或(第三方)包装成$ q承诺。当您处理可能会或可能不是承诺的对象,或者承诺来自不可信任的源时,这非常有用。
它使用了theables的概念将“不可信”的承诺转换为$ q承诺。
所以你要做的就是
var p = $q.when(value); // p is now always a $q promise
// if it already was one - no harm
答案 1 :(得分:4)
作为一个部分解决方案,对于给定的示例来说足够和适当,我们可以通过检查特定方法的存在来轻松区分jQuery.Deferred promises和Angular promise。例如,Angular的$ q promises有方法catch
来处理错误,而jQuery.Deferred的promises有方法fail
。
function promiseIsAngularOrJQuery(promise) {
if (typeof promise.fail === 'function') {
return 'jquery';
} else if (typeof promise.catch === 'function') {
return 'angular';
} else {
throw new Error("this can't be either type of promise!");
}
}
然而,使用这种技术来区分更多不同类型的承诺,或承诺与非承诺之间,可能会变得非常混乱。不同的实现经常使用许多相同的方法名称。它可能会起作用,但我不会走那条路。
有一种替代方案应该能够在合理的条件下可靠地识别$ q promises:在非恶意环境中对可信对象进行操作,只使用单个版本的Angular。但是,有些人可能会认为它太“黑”而无法认真使用。
如果使用String()
函数将函数转换为字符串,则结果是该函数的源代码。我们只需要使用它来将潜在promise对象的.then
方法与已知$ q promise对象的.then
方法进行比较:
function isAngularPromise(value) {
if (typeof value.then !== 'function') {
return false;
}
var promiseThenSrc = String($q.defer().promise.then);
var valueThenSrc = String(value.then);
return promiseThenSrc === valueThenSrc;
}
答案 2 :(得分:1)
我目前的解决方案是使用instanceof
:
var AngularPromise = $q.resolve().constructor;
console.log($q.resolve() instanceof AngularPromise); // true
如果对象确实是Angular Promise,则保证返回true。