我试图添加一个实用程序方法来将通知侦听器附加到Angular的$q
承诺中,默认情况下由于某种原因未提供这些承诺。目的是提供一个可链接的.update
方法,类似于现有的API:
myService.getSomeValue()
.then(function() { /* ... */ })
.catch(function() { /* ... */ })
.update(function() {
// do something useful with a notification update
});
以Get state of Angular deferred?中的答案为导向,并从Angular documentation for $q和source code看到catch
被简单地定义为promise.then(null, callback)
,我&# 39;已实现此配置块:
.config(['$provide', function($provide) {
$provide.decorator('$q', function ($delegate) {
var defer = $delegate.defer;
$delegate.defer = function() {
var deferred = defer();
deferred.promise.update = function(callback) {
return deferred.promise.then(null, null, callback);
};
return deferred;
};
return $delegate;
});
}]);
哪种作品,但似乎上面的装饰器没有立即设置,这打破了链接界面。第一次定义$q.defer()
(可能是每个块?)
first.promise
.then(function() { /* ... */ })
.update(function() {
// do something useful with a notification update
});
抛出TypeError: first.promise.then(...).update is not a function
。
此处示例:http://plnkr.co/edit/5utIm0HXpIKsjsA4H9oS
当我写一个简单的例子时,我才注意到这一点,当我从服务中返回承诺并且已经使用了其他承诺时,我已经使用了这个代码而没有问题(如果这可能会有一种影响?)。有没有办法让plunker示例在链接时可靠地工作?
答案 0 :(得分:1)
Deferred和Promise是Angular中的两个不同的API,这种方式只有the promise belonging to defer
被装饰,而the promise returned from then
则没有。
它们都使用Promise()
构造函数,它不会在$q
的任何位置公开。但是,Promise.prototype可以使用
Object.getPrototypeOf(deferred.promise).update = function(callback) { ... };