javascriptangularsettimeoutangular-changedetectionzone

Why ngDoCheck is called when setTimeout is resolved?


I'm trying to understand why ngDoCheck runs when setTimeout is resolved.

I've a simple component like this.

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css'],
})
export class ChildComponent implements DoCheck {

  constructor(private cd: ChangeDetectorRef) {
 
    setTimeout(() => {
      console.log('setTimeout done');
      // DoCheck runs
    }, 5000);

  }


  ngDoCheck(): void {
    console.log('Child DoCheck: ');
  }


}

after 5 secs, I get logs like:

setTimeout done
Child DoCheck: 

Why ngDoCheck was called? even though no state/model/binding was updated

I get the general concept when ngDoCheck is called:

Is there some sort of binding of promises, setTimeout with zone js that calls ngDoCheck whenever the call is resolved?

If so, I want to see zonejs code or any actual source from docs that confirms it.

Also, what is the purpose of calling ngDoCheck when simply console logging a setTimeout? I mean this use case application.


Solution

  • As mentioned in angular documentation:

    Zone.js is a signaling mechanism that Angular uses to detect when an application state might have changed. It captures asynchronous operations like setTimeout, network requests, and event listeners. Angular schedules change detection based on signals from Zone.js

    Here is the code from angular repo how it monkey patches setTimeout

    Zone.__load_patch('timers', (global: any) => {
      const set = 'set';
      const clear = 'clear';
      patchTimer(global, set, clear, 'Timeout');
      patchTimer(global, set, clear, 'Interval');
      patchTimer(global, set, clear, 'Immediate');
    });
    

    Source code for patchTime