Skip to content

Commit 15dab7c

Browse files
committed
fix(ng_zone): updated zone not to run onTurnDown when invoking run synchronously from onTurnDone
1 parent 37f8fd6 commit 15dab7c

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class NgZone {
3939
// }); // we should only check for the end of a turn once the top-level run ends
4040
int _nestedRun = 0;
4141

42+
bool _inVmTurnDone = false;
43+
4244
/**
4345
* Associates with this
4446
*
@@ -143,12 +145,14 @@ class NgZone {
143145
} finally {
144146
_nestedRun--;
145147
// If there are no more pending microtasks and we are not in a recursive call, this is the end of a turn
146-
if (_pendingMicrotasks == 0 && _nestedRun == 0) {
148+
if (_pendingMicrotasks == 0 && _nestedRun == 0 && !_inVmTurnDone) {
147149
if (_onTurnDone != null && _hasExecutedCodeInInnerZone) {
148150
// Trigger onTurnDone at the end of a turn if _innerZone has executed some code
149151
try {
152+
_inVmTurnDone = true;
150153
parent.run(_innerZone, _onTurnDone);
151154
} finally {
155+
_inVmTurnDone = false;
152156
_hasExecutedCodeInInnerZone = false;
153157
}
154158
}

modules/angular2/src/core/zone/ng_zone.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ export class NgZone {
3939
// This disabled flag is only here to please cjs tests
4040
_disabled: boolean;
4141

42+
_inVmTurnDone: boolean = false;
43+
4244
/**
4345
* Associates with this
4446
*
@@ -166,11 +168,14 @@ export class NgZone {
166168
// _nestedRun will be 0 at the end of a macrotasks (it could be > 0 when there are
167169
// nested calls
168170
// to run()).
169-
if (ngZone._pendingMicrotasks == 0 && ngZone._nestedRun == 0) {
171+
if (ngZone._pendingMicrotasks == 0 && ngZone._nestedRun == 0 &&
172+
!this._inVmTurnDone) {
170173
if (ngZone._onTurnDone && ngZone._hasExecutedCodeInInnerZone) {
171174
try {
175+
this._inVmTurnDone = true;
172176
parentRun.call(ngZone._innerZone, ngZone._onTurnDone);
173177
} finally {
178+
this._inVmTurnDone = false;
174179
ngZone._hasExecutedCodeInInnerZone = false;
175180
}
176181
}

modules/angular2/test/core/zone/ng_zone_spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,30 @@ function commonTests() {
200200
}, 50);
201201
}));
202202

203+
it('should not run onTurnStart and onTurnDone for nested Zone.run invoked from onTurnDone',
204+
inject([AsyncTestCompleter], (async) => {
205+
_zone.initCallbacks({
206+
onTurnDone: () => {
207+
_log.add('onTurnDone:started');
208+
_zone.run(() => _log.add('nested run'))
209+
_log.add('onTurnDone:finished');
210+
}
211+
});
212+
213+
macroTask(() => {
214+
_zone.run(() => {
215+
_log.add('start run');
216+
});
217+
});
218+
219+
macroTask(() => {
220+
expect(_log.result())
221+
.toEqual(
222+
'start run; onTurnDone:started; nested run; onTurnDone:finished');
223+
async.done();
224+
}, 50);
225+
}));
226+
203227
it('should call onTurnStart and onTurnDone before and after each top-level run',
204228
inject([AsyncTestCompleter], (async) => {
205229
macroTask(() => { _zone.run(_log.fn('run1')); });

0 commit comments

Comments
 (0)