Skip to content

Commit c75e216

Browse files
committed
refactor(VmTurnZone): outer zone = root zone
1 parent fd1d60f commit c75e216

File tree

5 files changed

+106
-199
lines changed

5 files changed

+106
-199
lines changed

modules/angular2/src/core/zone/vm_turn_zone.dart

Lines changed: 23 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,10 @@ class VmTurnZone {
2929
// onTurnDone hook at the end of the current VM turn.
3030
Zone _innerZone;
3131

32-
// Number of microtasks pending from _outerZone (& descendants)
32+
// Number of microtasks pending from _innerZone (& descendants)
3333
int _pendingMicrotasks = 0;
3434
// Whether some code has been executed in the _innerZone (& descendants) in the current turn
3535
bool _hasExecutedCodeInInnerZone = false;
36-
// Whether the onTurnStart hook is executing
37-
bool _inTurnStart = false;
3836
// _outerRun() call depth. 0 at the end of a macrotask
3937
// zone.run(() => { // top-level call
4038
// zone.run(() => {}); // nested call -> in-turn
@@ -44,36 +42,26 @@ class VmTurnZone {
4442
/**
4543
* Associates with this
4644
*
47-
* - an "outer" [Zone], which is a child of the one that created this.
45+
* - an "outer" [Zone], which is a the one that created this.
4846
* - an "inner" [Zone], which is a child of the outer [Zone].
4947
*
5048
* @param {bool} enableLongStackTrace whether to enable long stack trace. They should only be
5149
* enabled in development mode as they significantly impact perf.
5250
*/
5351
VmTurnZone({bool enableLongStackTrace}) {
54-
// The _outerZone captures microtask scheduling so that we can run onTurnDone when the queue
55-
// is exhausted and code has been executed in the _innerZone.
52+
_outerZone = Zone.current;
53+
5654
if (enableLongStackTrace) {
57-
_outerZone = Chain.capture(
58-
() => _createOuterZone(Zone.current),
55+
_innerZone = Chain.capture(
56+
() => _createInnerZone(Zone.current),
5957
onError: _onErrorWithLongStackTrace);
6058
} else {
61-
_outerZone = _createOuterZone(
59+
_innerZone = _createInnerZone(
6260
Zone.current,
6361
handleUncaughtError: (Zone self, ZoneDelegate parent, Zone zone, error, StackTrace trace) =>
6462
_onErrorWithoutLongStackTrace(error, trace)
6563
);
6664
}
67-
68-
// Instruments the inner [Zone] to detect when code is executed in this (or a descendant) zone.
69-
// Also runs the onTurnStart hook the first time this zone executes some code in each turn.
70-
_innerZone = _outerZone.fork(
71-
specification: new ZoneSpecification(
72-
run: _innerRun,
73-
runUnary: _innerRunUnary,
74-
runBinary: _innerRunBinary
75-
),
76-
zoneValues: {'_name': 'inner'});
7765
}
7866

7967
/**
@@ -136,47 +124,28 @@ class VmTurnZone {
136124
* ```
137125
*/
138126
dynamic runOutsideAngular(fn()) {
139-
return _outerZone.runGuarded(fn);
140-
}
141-
142-
// Executes code in the [_innerZone] & trigger the onTurnStart hook when code is executed for the
143-
// first time in a turn.
144-
dynamic _innerRun(Zone self, ZoneDelegate parent, Zone zone, fn()) {
145-
_maybeStartVmTurn(parent, zone);
146-
return parent.run(zone, fn);
147-
}
148-
149-
dynamic _innerRunUnary(Zone self, ZoneDelegate parent, Zone zone, fn(arg), arg) {
150-
_maybeStartVmTurn(parent, zone);
151-
return parent.runUnary(zone, fn, arg);
152-
}
153-
154-
dynamic _innerRunBinary(Zone self, ZoneDelegate parent, Zone zone, fn(arg1, arg2), arg1, arg2) {
155-
_maybeStartVmTurn(parent, zone);
156-
return parent.runBinary(zone, fn, arg1, arg2);
127+
return _outerZone.run(fn);
157128
}
158129

159-
void _maybeStartVmTurn(ZoneDelegate parent, Zone zone) {
130+
void _maybeStartVmTurn(ZoneDelegate parent) {
160131
if (!_hasExecutedCodeInInnerZone) {
161132
_hasExecutedCodeInInnerZone = true;
162133
if (_onTurnStart != null) {
163-
_inTurnStart = true;
164-
parent.run(zone, _onTurnStart);
134+
parent.run(_innerZone, _onTurnStart);
165135
}
166136
}
167137
}
168138

169-
dynamic _outerRun(Zone self, ZoneDelegate parent, Zone zone, fn()) {
139+
dynamic _run(Zone self, ZoneDelegate parent, Zone zone, fn()) {
170140
try {
171141
_nestedRun++;
142+
_maybeStartVmTurn(parent);
172143
return parent.run(zone, fn);
173144
} finally {
174145
_nestedRun--;
175-
// If there are no more pending microtasks, we are at the end of a VM turn (or in onTurnStart)
176-
// _nestedRun will be 0 at the end of a macrotasks (it could be > 0 when there are nested calls
177-
// to _outerRun()).
146+
// If there are no more pending microtasks and we are not in a recursive call, this is the end of a turn
178147
if (_pendingMicrotasks == 0 && _nestedRun == 0) {
179-
if (_onTurnDone != null && !_inTurnStart && _hasExecutedCodeInInnerZone) {
148+
if (_onTurnDone != null && _hasExecutedCodeInInnerZone) {
180149
// Trigger onTurnDone at the end of a turn if _innerZone has executed some code
181150
try {
182151
parent.run(_innerZone, _onTurnDone);
@@ -185,15 +154,14 @@ class VmTurnZone {
185154
}
186155
}
187156
}
188-
_inTurnStart = false;
189157
}
190158
}
191159

192-
dynamic _outerRunUnary(Zone self, ZoneDelegate parent, Zone zone, fn(arg), arg) =>
193-
_outerRun(self, parent, zone, () => fn(arg));
160+
dynamic _runUnary(Zone self, ZoneDelegate parent, Zone zone, fn(arg), arg) =>
161+
_run(self, parent, zone, () => fn(arg));
194162

195-
dynamic _outerRunBinary(Zone self, ZoneDelegate parent, Zone zone, fn(arg1, arg2), arg1, arg2) =>
196-
_outerRun(self, parent, zone, () => fn(arg1, arg2));
163+
dynamic _runBinary(Zone self, ZoneDelegate parent, Zone zone, fn(arg1, arg2), arg1, arg2) =>
164+
_run(self, parent, zone, () => fn(arg1, arg2));
197165

198166
void _scheduleMicrotask(Zone self, ZoneDelegate parent, Zone zone, fn) {
199167
_pendingMicrotasks++;
@@ -226,16 +194,16 @@ class VmTurnZone {
226194
}
227195
}
228196

229-
Zone _createOuterZone(Zone zone, {handleUncaughtError}) {
197+
Zone _createInnerZone(Zone zone, {handleUncaughtError}) {
230198
return zone.fork(
231199
specification: new ZoneSpecification(
232200
scheduleMicrotask: _scheduleMicrotask,
233-
run: _outerRun,
234-
runUnary: _outerRunUnary,
235-
runBinary: _outerRunBinary,
201+
run: _run,
202+
runUnary: _runUnary,
203+
runBinary: _runBinary,
236204
handleUncaughtError: handleUncaughtError
237205
),
238-
zoneValues: {'_name': 'outer'}
206+
zoneValues: {'_innerZone': true}
239207
);
240208
}
241209
}

modules/angular2/src/core/zone/vm_turn_zone.es6

Lines changed: 42 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ export class VmTurnZone {
2727
_pendingMicrotask: number;
2828
// Whether some code has been executed in the _innerZone (& descendants) in the current turn
2929
_hasExecutedCodeInInnerZone: boolean;
30-
// Whether the onTurnStart hook is executing
31-
_inTurnStart: boolean;
3230
// run() call depth in _outerZone. 0 at the end of a macrotask
3331
// zone.run(() => { // top-level call
3432
// zone.run(() => {}); // nested call -> in-turn
@@ -51,11 +49,10 @@ export class VmTurnZone {
5149

5250
this._pendingMicrotasks = 0;
5351
this._hasExecutedCodeInInnerZone = false;
54-
this._inTurnStart = false;
5552
this._nestedRun = 0;
5653

57-
this._outerZone = this._createOuterZone(global.zone);
58-
this._innerZone = this._createInnerZone(this._outerZone, enableLongStackTrace);
54+
this._outerZone = global.zone;
55+
this._innerZone = this._createInnerZone(this._outerZone, enableLongStackTrace)
5956
}
6057

6158
/**
@@ -109,50 +106,6 @@ export class VmTurnZone {
109106
return this._outerZone.run(fn);
110107
}
111108

112-
_createOuterZone(zone) {
113-
var vmTurnZone = this;
114-
115-
return zone.fork({
116-
_name: 'outer',
117-
'$run': function(parentRun) {
118-
return function() {
119-
try {
120-
vmTurnZone._nestedRun++;
121-
return parentRun.apply(this, arguments);
122-
} finally {
123-
vmTurnZone._nestedRun--;
124-
// If there are no more pending microtasks, we are at the end of a VM turn (or in onTurnStart)
125-
// _nestedRun will be 0 at the end of a macrotasks (it could be > 0 when there are nested calls
126-
// to run()).
127-
if (vmTurnZone._pendingMicrotasks == 0 && vmTurnZone._nestedRun == 0) {
128-
if (vmTurnZone._onTurnDone && !vmTurnZone._inTurnStart && vmTurnZone._hasExecutedCodeInInnerZone) {
129-
try {
130-
parentRun.call(vmTurnZone._innerZone, vmTurnZone._onTurnDone);
131-
} finally {
132-
vmTurnZone._hasExecutedCodeInInnerZone = false;
133-
}
134-
}
135-
}
136-
vmTurnZone._inTurnStart = false;
137-
}
138-
}
139-
},
140-
'$scheduleMicrotask': function(parentScheduleMicrotask) {
141-
return function(fn) {
142-
vmTurnZone._pendingMicrotasks++;
143-
var microtask = function() {
144-
try {
145-
fn();
146-
} finally {
147-
vmTurnZone._pendingMicrotasks--;
148-
}
149-
};
150-
parentScheduleMicrotask.call(this, microtask);
151-
}
152-
}
153-
});
154-
}
155-
156109
_createInnerZone(zone, enableLongStackTrace) {
157110
var vmTurnZone = this;
158111
var errorHandling;
@@ -174,28 +127,51 @@ export class VmTurnZone {
174127
return zone
175128
.fork(errorHandling)
176129
.fork({
177-
// Executes code in the _innerZone & trigger the onTurnStart hook when code is executed for the
178-
// first time in a turn.
179-
'$run': function (parentRun) {
180-
return function () {
181-
vmTurnZone._maybeStartVmTurn()
182-
return parentRun.apply(this, arguments)
130+
'$run': function(parentRun) {
131+
return function() {
132+
try {
133+
vmTurnZone._nestedRun++;
134+
if (!vmTurnZone._hasExecutedCodeInInnerZone) {
135+
vmTurnZone._hasExecutedCodeInInnerZone = true;
136+
if (vmTurnZone._onTurnStart) {
137+
parentRun.call(vmTurnZone._innerZone, vmTurnZone._onTurnStart);
138+
}
139+
}
140+
return parentRun.apply(this, arguments);
141+
} finally {
142+
vmTurnZone._nestedRun--;
143+
// If there are no more pending microtasks, we are at the end of a VM turn (or in onTurnStart)
144+
// _nestedRun will be 0 at the end of a macrotasks (it could be > 0 when there are nested calls
145+
// to run()).
146+
if (vmTurnZone._pendingMicrotasks == 0 && vmTurnZone._nestedRun == 0) {
147+
if (vmTurnZone._onTurnDone && vmTurnZone._hasExecutedCodeInInnerZone) {
148+
try {
149+
parentRun.call(vmTurnZone._innerZone, vmTurnZone._onTurnDone);
150+
} finally {
151+
vmTurnZone._hasExecutedCodeInInnerZone = false;
152+
}
153+
}
154+
}
155+
}
156+
}
157+
},
158+
'$scheduleMicrotask': function(parentScheduleMicrotask) {
159+
return function(fn) {
160+
vmTurnZone._pendingMicrotasks++;
161+
var microtask = function() {
162+
try {
163+
fn();
164+
} finally {
165+
vmTurnZone._pendingMicrotasks--;
166+
}
167+
};
168+
parentScheduleMicrotask.call(this, microtask);
183169
}
184170
},
185-
_name: 'inner'
171+
_innerZone: true
186172
});
187173
}
188174

189-
_maybeStartVmTurn(): void {
190-
if (!this._hasExecutedCodeInInnerZone) {
191-
this._hasExecutedCodeInInnerZone = true;
192-
if (this._onTurnStart) {
193-
this._inTurnStart = true;
194-
this._outerZone.run.call(this._innerZone, this._onTurnStart);
195-
}
196-
}
197-
}
198-
199175
_onError(zone, e): void {
200176
if (isPresent(this._onErrorHandler)) {
201177
var trace = [normalizeBlank(e.stack)];

modules/angular2/src/test_lib/test_lib.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,4 +226,4 @@ String elementText(n) {
226226
return DOM.getText(n);
227227
}
228228

229-
String getCurrentZoneName() => Zone.current['_name'];
229+
bool isInInnerZone() => Zone.current['_innerZone'] == true;

modules/angular2/src/test_lib/test_lib.es6

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,6 @@ function elementText(n) {
354354
return DOM.getText(n);
355355
}
356356

357-
function getCurrentZoneName(): string {
358-
return global.zone._name;
357+
export function isInInnerZone(): boolean {
358+
return global.zone._innerZone === true;
359359
}

0 commit comments

Comments
 (0)