javascript - 准确跟踪由 $q.defer 调用的 Angular 的事件/完成 promise

标签 javascript angularjs profiling promise angular-promise

对于我的 Angular 应用程序,我试图跟踪有多少 promise 已经处理,还有多少还需要处理。

我的代码用包装器方法装饰 $q,这些方法在操作开​​始和完成时更新一个简单的计数器,看起来很简单:

  angular.module('DuckieTV',[])
  .config(function($provide) {
  var count = window.promiseStats = { 
    open: 0,
    done: 0 
  };
  $provide.decorator('$q', function($delegate) {

    function decorate(p) {
      p._then = p.then;
      p.then = function(thenFn, errFn, notifyFn) {
       count.open++;
       return p._then(function() { 
            count.done++;
            if(thenFn) return thenFn.apply(this,arguments)
        }, function() {
          count.done++;
          if(errFn) return errFn.apply(this,arguments)
        }, notifyFn);
      };

      p._finally = p.finally;
      p.finally = function(callback) {
        count.done++;
        p._finally(callback)
      }

      p._catch = p.catch;
      p.catch = function(callback) {
        count.done++;
        p._catch(callback)
      }
      return p;
    }

    var d = $delegate.defer;
    $delegate.defer = function() {
      var deferred = d();
      decorate(deferred.promise);
      return deferred;
    };

    return $delegate;
  });
})

当我注意到开始/完成的 promise 之间存在差异时,乐趣就开始了。在执行大量延迟操作几分钟后,总体百分比可能会超过 15%。

示例控制台输出:

promiseStats
Object {open: 99, done: 95}
Math.floor(promiseStats.done / promiseStats.open * 100);
94

经过一些工作(导入操作)

promiseStats;
Object {open: 185, done: 172}
Math.floor(promiseStats.done / promiseStats.open * 100);
92

我的实际问题:任何人都可以告诉我这个实现是否遗漏了什么吗?

据我所知,我没有错过可选的实现,并且我通过 .then 触发的所有 promise 都已正确编码

最佳答案

Can anyone tell me if i'm missing something with this implementation?

我发现您的实现存在两个问题:

  • 您修饰的catchinvoke 方法只会增加done 计数,而不会增加open 计数。既然你没有看到这个,我猜你没有在你的代码中使用过。
  • 通过在每个 .then() 调用中引入一个 onfail 处理程序,您可以隐式地捕获所有错误并严重 hurt control flow .您可以通过将以下行附加到您的处理程序代码来解决此问题:

     …
     else throw arguments[0];
    

I'm noticing a discrepancy between started/finished promises

我认为这不是您实现计数器造成的。相反,您真的在您的代码中有一些永远未决的 promise ;即永远不会解决的延迟。例如,这可能是由使用 deferred antipattern 的代码错误引起的.

My code decorates $q with wrapper methods that update a simple counter whenever an operation is started and whenever one is finished, seems simple:

事实上,只要有监听器,它就会更新计数器,即 then/catch/finally 方法被调用。我会提出一个更简单的实现,它依赖于创建,甚至不需要覆盖方法:

$provide.decorator('$q', function($delegate) {
    var defer = $delegate.defer;
    $delegate.defer = function() {
        var deferred = defer();
        count.open++;
        deferred.promise.finally(function() {
            count.done++;
        });
        return deferred;
    };
    return $delegate;
});

关于javascript - 准确跟踪由 $q.defer 调用的 Angular 的事件/完成 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26372129/

相关文章:

javascript - 为什么我的即时搜索不起作用?

javascript - 如果对象包含真键,则返回 bool 真值,不返回值

jquery - 随机颜色 ng-repeat 内的 Div,元素数量未知

javascript - 在 requirejs 模块 javascript 的函数内部调用函数

Javascript parseInt 或 + ,追加而不是添加

javascript - 2 路数据绑定(bind)指令 Angular

javascript - AngularJS 使用循环向对象插入新属性

linux - oprofile 不对 LLC_MISSES 缓存事件进行采样

performance - 向量化三个 for 循环

java - 第二次排序更快