angular/packages/core/test
JiaLiPassion 22f9e454a4 fix(core): NgZone coaleascing options should trigger onStable correctly (#40540)
fix https://github.com/angular/components/issues/21674

When setting `ngZoneRunCoalescing` to true, `onStable` is not emitted correctly.
The reason is before this commit, the code looks like this

```
// Application code call `ngZone.run()`
ngZone.run(() => {}); // step 1

// Inside NgZone, in the OnInvoke hook, NgZone try to delay the checkStable()

function delayChangeDetectionForEvents(zone: NgZonePrivate) {
  if (zone.lastRequestAnimationFrameId !== -1) { // step 9
    return;
  }
  zone.lastRequestAnimationFrameId = zone.nativeRequestAnimationFrame.call(global, () => { // step 2
    if (!zone.fakeTopEventTask) {
      zone.fakeTopEventTask = Zone.root.scheduleEventTask('fakeTopEventTask', () => {
        zone.lastRequestAnimationFrameId = -1; // step 3
        updateMicroTaskStatus(zone); // step 4
        checkStable(zone); // step 6
      }, undefined, () => {}, () => {});
    }
    zone.fakeTopEventTask.invoke();
  });
  updateMicroTaskStatus(zone);
}

function updateMicroTaskStatus(zone: NgZonePrivate, ignoreCheckRAFId = false) {
  if (zone._hasPendingMicrotasks ||
      ((zone.shouldCoalesceEventChangeDetection || zone.shouldCoalesceRunChangeDetection) &&
       zone.lastRequestAnimationFrameId !== -1)) { // step 5
    zone.hasPendingMicrotasks = true;
  } else {
    zone.hasPendingMicrotasks = false;
  }
}

function checkStable(zone: NgZonePrivate) {
  if (zone._nesting == 0 && !zone.hasPendingMicrotasks && !zone.isStable) { // step 7
    try {
      zone._nesting++;
      zone.onMicrotaskEmpty.emit(null);
    ...
}

// application ref subscribe onMicroTaskEmpty
ngZone.onMicroTaskEmpty.subscribe(() => {
  ngZone.run(() => { // step 8
    tick();
  });
});

```

And the process is:
1. step 1: application call ngZone.run()
2. step 2: NgZone delay the checkStable() call in a requestAnimationFrame, and also set
zone.lastRequestAnimationFrameId
3. step 3: Inside the requestAnimationFrame callback, reset zone.lastRequestAnimationFrameId first
4. step 4: update microTask status
5, step 5: if zone.lastRequestAnimationFrameId is -1, that means no microTask pending.
6. step 6: checkStable and trigger onMicrotaskEmpty emitter.
7. step 7: ApplicationRef subscribed onMicrotaskEmpty, so it will call another `ngZone.run()` to process
tick()
8. step 8: And this new `ngZone.run()` will try to check `zone.lastRequestAnimationFrameId` in `step 9`
when trying to delay the checkStable(), and since the zone.lastRequestAnimationFrameId is already reset
to -1 in step 3, so this ngZone.run() will run into step 2 again.
9. And become a infinite loop..., so onStable is never emit

In this commit, the `zone.lastRequestAnimationFrameId` reset is moved after `checkStable()` call.

PR Close #40540
2021-01-28 15:53:38 -08:00
..
acceptance fix(core): fix possible XSS attack in development through SSR (#40525) 2021-01-26 09:32:27 -08:00
animation fix(core): Store ICU state in LView rather than in TView (#39233) 2020-10-21 18:33:00 -07:00
bundling Revert "fix(core): remove duplicated EMPTY_ARRAY constant (#40587)" 2021-01-28 14:35:03 -08:00
change_detection fix(core): make DefaultIterableDiffer keep the order of duplicates (#23941) 2021-01-26 15:44:42 -08:00
debug feat(core): update reference and doc to change async to waitAsync. (#37583) 2020-08-03 12:54:13 -07:00
di perf(core): make DI decorators tree-shakable when used for useFactory deps config (#40145) 2021-01-13 14:08:45 -08:00
dom build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
i18n build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
linker refactor(core): add links to top runtime errors (#40326) 2021-01-19 10:14:56 -08:00
metadata build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
reflection fix(core): detect DI parameters in JIT mode for downleveled ES2015 classes (#38463) 2020-08-17 10:55:37 -07:00
render3 fix(core): improve injector debug information in ngDevMode (#40476) 2021-01-22 10:21:25 -08:00
sanitization fix(core): ensure sanitizer works if DOMParser return null body (#40107) 2021-01-06 10:32:24 -08:00
strict_types build: upgrade angular build, integration/bazel and @angular/bazel package to rule_nodejs 2.2.0 (#39182) 2020-10-08 11:54:59 -07:00
testability feat(core): update reference and doc to change async to waitAsync. (#37583) 2020-08-03 12:54:13 -07:00
util fix(core): fix possible XSS attack in development through SSR (#40525) 2021-01-26 09:32:27 -08:00
view refactor(core): Cleanup non-standard Injector handling. (#39621) 2020-11-16 09:12:46 -08:00
zone fix(core): NgZone coaleascing options should trigger onStable correctly (#40540) 2021-01-28 15:53:38 -08:00
application_init_spec.ts feat(core): update reference and doc to change async to waitAsync. (#37583) 2020-08-03 12:54:13 -07:00
application_module_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
application_ref_integration_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
application_ref_spec.ts feat(core): update reference and doc to change async to waitAsync. (#37583) 2020-08-03 12:54:13 -07:00
BUILD.bazel fix(core): detect DI parameters in JIT mode for downleveled ES2015 classes (#38463) 2020-08-17 10:55:37 -07:00
component_fixture_spec.ts feat(core): update reference and doc to change async to waitAsync. (#37583) 2020-08-03 12:54:13 -07:00
dev_mode_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
directive_lifecycle_integration_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
error_handler_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
event_emitter_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
fake_async_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
forward_ref_integration_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
spies.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
test_bed_async_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
test_bed_spec.ts fix(core): reset tView between tests in Ivy TestBed (#38659) 2020-09-03 09:44:22 -07:00
testing_internal_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
util_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00