Search code examples
angularzone

zone.afterTask and zone.beforeTask hook methods not working


I'm trying to implement simple zone.afterTask and beforeTask hooks but though code ain't throwing any error , those methods are never getting called.

I searched Zone repo in github , and couldn't find any reference to these methods in the source code apart from the ones that's used in the example. counting example does use afterTask and beforeTask but I've set a debugger and saw those methods are never getting called in their example as well .

It looks like these methods have been deprecated , If not kindly let me know what I'm doing wrong.

Here's my code -

import { Component } from 'angular2/core';

@Component({
  template: `
      <div>
        <p>Basic use of Zone</p>
        <button (click)="startTask()">Start Task</button>
        <p> Time taken {{timeTaken}}</p>
      </div>
    `
})
export class HelloZone {
  timeTaken: any;

  task1(){
    for (let i = 0; i < 1e5; i++);
  }

  startTask() {
    let startTime;

    let myZone = Zone.parent.fork({
      beforeTask: function() {
        startTime = new Date();
      },
      afterTask: function() {
        this.timeTaken = new Date() - startTime;
      }
    });
    myZone.run(function(){
      this.task1();
      setTimeout(this.task1, 2000);
      this.task1();
    }.bind(this));
  }
}

Solution

  • I think that for your use case, you can leverage onInvokeTask and onHasTask hooks as described below:

    export class HelloZone {
      timeTaken: any;
    
      constructor(private zone:NgZone) {
    
      }
    
      (...)
    
      startTask() {
        let startTime;
    
        let myZone = Zone.current.fork({
          onInvokeTask: (parent, current, target, task) => {
            startTime = new Date();
            parent.invokeTask(target, task);
          },
          onHasTask: (parent, current, target, hasTask) => {
            if (!hasTask.macroTask) {
              this.zone.run(() => {
                this.timeTaken = new Date() - startTime;
              });
            }
          }
        });
        myZone.run(() => {
          this.task1();
          setTimeout(this.task1, 2000);
          this.task1();
        });
      }
    }
    

    See this plunkr: https://plnkr.co/edit/EH8uy66ke1i61QhE9fYi?p=preview.