diff --git a/goldens/size-tracking/integration-payloads.json b/goldens/size-tracking/integration-payloads.json index 3150c5b8da..b46bef621a 100644 --- a/goldens/size-tracking/integration-payloads.json +++ b/goldens/size-tracking/integration-payloads.json @@ -4,7 +4,7 @@ "uncompressed": { "runtime-es2015": 1485, "main-es2015": 140899, - "polyfills-es2015": 36571 + "polyfills-es2015": 36964 } } }, @@ -22,7 +22,7 @@ "uncompressed": { "runtime-es2015": 1485, "main-es2015": 146698, - "polyfills-es2015": 36571 + "polyfills-es2015": 36964 } } }, @@ -31,7 +31,7 @@ "uncompressed": { "runtime-es2015": 1485, "main-es2015": 136062, - "polyfills-es2015": 37392 + "polyfills-es2015": 37641 } } }, diff --git a/packages/zone.js/lib/browser/browser.ts b/packages/zone.js/lib/browser/browser.ts index bf6c419528..a6190c42ef 100644 --- a/packages/zone.js/lib/browser/browser.ts +++ b/packages/zone.js/lib/browser/browser.ts @@ -25,6 +25,15 @@ Zone.__load_patch('legacy', (global: any) => { } }); +Zone.__load_patch('queueMicrotask', (global: any, Zone: ZoneType, api: _ZonePrivate) => { + api.patchMethod(global, 'queueMicrotask', delegate => { + return function(self: any, args: any[]) { + Zone.current.scheduleMicroTask('queueMicrotask', args[0]); + } + }); +}); + + Zone.__load_patch('timers', (global: any) => { const set = 'set'; const clear = 'clear'; diff --git a/packages/zone.js/lib/zone.configurations.api.ts b/packages/zone.js/lib/zone.configurations.api.ts index c53c81dd2b..c45ae9bb2a 100644 --- a/packages/zone.js/lib/zone.configurations.api.ts +++ b/packages/zone.js/lib/zone.configurations.api.ts @@ -294,6 +294,34 @@ interface ZoneGlobalConfigurations { */ __Zone_disable_requestAnimationFrame?: boolean; + /** + * + * Disable the monkey patching of the browser's `queueMicrotask()` API. + * + * By default, `zone.js` monkey patches the browser's `queueMicrotask()` API + * to ensure that `queueMicrotask()` callback is invoked in the same zone as zone used to invoke + * `queueMicrotask()`. And also the callback is running as `microTask` like + * `Promise.prototype.then()`. + * + * Consider the following example: + * + * ``` + * const zone = Zone.current.fork({name: 'myZone'}); + * zone.run(() => { + * queueMicrotask(() => { + * console.log('queueMicrotask() callback is invoked in the zone', Zone.current.name); + * // Since `queueMicrotask()` was invoked in `myZone`, same zone is restored + * // when 'queueMicrotask() callback is invoked, resulting in `myZone` being console logged. + * }); + * }); + * ``` + * + * If you set `__Zone_disable_queueMicrotask = true` before importing `zone.js`, + * `zone.js` does not monkey patch the `queueMicrotask()` API and the above code + * output will change to: 'queueMicrotask() callback is invoked in the zone '. + */ + __Zone_disable_queueMicrotask?: boolean; + /** * * Disable the monkey patch of the browser blocking APIs(`alert()`/`prompt()`/`confirm()`). diff --git a/packages/zone.js/test/browser/queue-microtask.spec.ts b/packages/zone.js/test/browser/queue-microtask.spec.ts new file mode 100644 index 0000000000..da8101a59a --- /dev/null +++ b/packages/zone.js/test/browser/queue-microtask.spec.ts @@ -0,0 +1,33 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import {ifEnvSupports} from '../test-util'; + +describe( + 'queueMicrotask', ifEnvSupports('queueMicrotask', function() { + it('callback in the queueMicrotask should be scheduled as microTask in the zone', + (done: DoneFn) => { + const logs: string[] = []; + Zone.current + .fork({ + name: 'queueMicrotask', + onScheduleTask: (delegate: ZoneDelegate, curr: Zone, target: Zone, task: Task) => { + logs.push(task.type); + logs.push(task.source); + return delegate.scheduleTask(target, task); + } + }) + .run(() => { + queueMicrotask(() => { + expect(logs).toEqual(['microTask', 'queueMicrotask']); + expect(Zone.current.name).toEqual('queueMicrotask'); + done(); + }); + }); + }); + })); diff --git a/packages/zone.js/test/browser_entry_point.ts b/packages/zone.js/test/browser_entry_point.ts index 3297956f7c..3954d5e373 100644 --- a/packages/zone.js/test/browser_entry_point.ts +++ b/packages/zone.js/test/browser_entry_point.ts @@ -29,3 +29,4 @@ import './mocha-patch.spec'; import './jasmine-patch.spec'; import './browser/messageport.spec'; import './extra/cordova.spec'; +import './browser/queue-microtask.spec';