获得Angular的状态延期?

Eva*_*bbs 39 jquery promise angularjs angular-promise

随着jQuery延迟,我以前能够像这样检查当前状态:

var defer = $.Deferred();
defer.state();  //Returns the state of the deferred, eg 'resolved'
Run Code Online (Sandbox Code Playgroud)

Angular deferreds有没有办法做同样的事情?(甚至更好的承诺)

Ben*_*aum 84

更新:

由于$ q的重构,现在可以实现,尽管没有记录:

promise.$$state.status === 0 // pending
promise.$$state.status === 1 // resolved
promise.$$state.status === 2 // rejected
Run Code Online (Sandbox Code Playgroud)

原文:

与大多数promise库(Bluebird,Q,when,RSVP等)不同,$ q不公开同步检查API.

没有办法从外面实现这一目标.

您必须调用.then承诺,并且承诺履行时该处理程序中的代码将运行.

  • 以"$$"开头的属性应被视为私有API,而不是在您自己的代码中使用.但是,我认为,没有用于公开Angular承诺状态的公共API. (7认同)
  • 看起来它已添加到1.3.0 - https://github.com/angular/angular.js/blob/v1.3.0/src/ng/q.js.在此之前我找不到任何对$$州的引用. (3认同)
  • @muttonUp:-1似乎是第二个已解决的情况,如1.它用于表示解析后的值何时是函数,或者值是否需要传递给promise链.我想 - -1意味着"到目前为止很好,但我们有更多的代码在分辨率完成之前运行". (3认同)
  • 状态也可以是-1,但我不确定它的含义是什么?https://github.com/angular/angular.js/blob/v1.4.3/src/ng/q.js#L365 (2认同)

Gil*_*man 34

你的问题的答案是:是的,有办法.其他答案很好地涵盖了内置的限制$q.然而,这是很容易的状态属性添加到$q使用$provide服务的装饰功能.

  $provide.decorator('$q', function ($delegate) {
    var defer = $delegate.defer;
    $delegate.defer = function() {
      var deferred = defer();

      deferred.promise.state = deferred.state = 'pending';

      deferred.promise.then(function() {
        deferred.promise.state = deferred.state = 'fulfilled';
      }, function () {
        deferred.promise.state = deferred.state = 'rejected';
      }); 

      return deferred;
    };
    return $delegate;
  });
Run Code Online (Sandbox Code Playgroud)

将此装饰器放在config块中,并且所有$q实例化的延迟promise对象将具有state值为pending,fulfilledrejected的属性.

看看这个插头


持怀疑态度?

你正在有效地修改$ q本身,将每个延迟包装为另一个延迟

实际上情况并非如此.$q原来的defer()构造函数恰好被称为一次.它通过内部附加事件处理程序来简单地装饰其他功能then.[请注意,附加defer对象是由于then每个延迟对象自动创建的附加回调的实例化...这是预期的,因为这是角度在内部工作的方式.

这不起作用,因为promises不应该使用deferred创建,而是链接自apis返回的promise

请注意,此代码将修饰由服务创建的每个延迟(因此promise对象)$q.这意味着任何使用$ q的API都将自动使用该state属性进行修饰.所以无论你如何使用$q,无论是使用某种API还是使用它,这个解决方案都会装饰deferred对象和它promise,并且我已经提供证明它的插件.


生产价值?

这种方法是单元可测试的,它保证不会破坏已经使用的任何应用程序$q,并且在以后意义上是灵活的,您可以在以后添加其他装饰器$q而不修改旧的装饰器.

  • @NateBarbettini很好 - 有一件事$ q在1.2的寿命期间经历了几次重大改变,1.2和1.3之间的巨大内部改革,几乎经历了更大的改革.今天你完全不同地做这件事(延迟和承诺是基于原型的) - 你可以直接覆盖`.then`而不需要这个解决方案的开销(通过Angular_创建一个开销并为每一个承诺分配一个额外的闭包)承诺很慢在Angular中(最近变得更好). (2认同)
  • 我很想听到promises的用例,其中实例化一个闭包和每个promise的一些简单对象会产生任何可察觉的性能差异. (2认同)