angular-docs-cn/packages/core/test
JiaLiPassion dc9fd1aaef 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, there is a new flag `zone.isCheckStableRunning` added to
prevent re-entry when `shouldCoaleascing` flag is enabled.

PR Close #40540
2021-02-22 10:01:31 -08:00
..
acceptance fix(animations): properly track listeners for a removed element (#40712) 2021-02-09 10:50:19 -08:00
animation fix(animations): properly track listeners for a removed element (#40712) 2021-02-09 10:50:19 -08:00
bundling feat(core): support APP_INITIALIZER work with observable (#33222) 2021-02-22 08:41:49 -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 fix(core): properly move embedded views of dynamic component's projectable nodes (#37167) 2021-02-10 11:03:06 -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 refactor(compiler-cli): implement `ɵɵngDeclarePipe()` (#40803) 2021-02-12 09:00:16 -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-02-22 10:01:31 -08:00
BUILD.bazel fix(core): detect DI parameters in JIT mode for downleveled ES2015 classes (#38463) 2020-08-17 10:55:37 -07:00
application_init_spec.ts test(core): refactor ApplicationInitStatus tests to avoid TestBed side-effects (#33222) 2021-02-22 08:41:49 -08: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
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