refactor(VmTurnZone): outer zone = root zone
This commit is contained in:
parent
fd1d60f03b
commit
c75e216871
|
@ -29,12 +29,10 @@ class VmTurnZone {
|
|||
// onTurnDone hook at the end of the current VM turn.
|
||||
Zone _innerZone;
|
||||
|
||||
// Number of microtasks pending from _outerZone (& descendants)
|
||||
// Number of microtasks pending from _innerZone (& descendants)
|
||||
int _pendingMicrotasks = 0;
|
||||
// Whether some code has been executed in the _innerZone (& descendants) in the current turn
|
||||
bool _hasExecutedCodeInInnerZone = false;
|
||||
// Whether the onTurnStart hook is executing
|
||||
bool _inTurnStart = false;
|
||||
// _outerRun() call depth. 0 at the end of a macrotask
|
||||
// zone.run(() => { // top-level call
|
||||
// zone.run(() => {}); // nested call -> in-turn
|
||||
|
@ -44,36 +42,26 @@ class VmTurnZone {
|
|||
/**
|
||||
* Associates with this
|
||||
*
|
||||
* - an "outer" [Zone], which is a child of the one that created this.
|
||||
* - an "outer" [Zone], which is a the one that created this.
|
||||
* - an "inner" [Zone], which is a child of the outer [Zone].
|
||||
*
|
||||
* @param {bool} enableLongStackTrace whether to enable long stack trace. They should only be
|
||||
* enabled in development mode as they significantly impact perf.
|
||||
*/
|
||||
VmTurnZone({bool enableLongStackTrace}) {
|
||||
// The _outerZone captures microtask scheduling so that we can run onTurnDone when the queue
|
||||
// is exhausted and code has been executed in the _innerZone.
|
||||
_outerZone = Zone.current;
|
||||
|
||||
if (enableLongStackTrace) {
|
||||
_outerZone = Chain.capture(
|
||||
() => _createOuterZone(Zone.current),
|
||||
_innerZone = Chain.capture(
|
||||
() => _createInnerZone(Zone.current),
|
||||
onError: _onErrorWithLongStackTrace);
|
||||
} else {
|
||||
_outerZone = _createOuterZone(
|
||||
_innerZone = _createInnerZone(
|
||||
Zone.current,
|
||||
handleUncaughtError: (Zone self, ZoneDelegate parent, Zone zone, error, StackTrace trace) =>
|
||||
_onErrorWithoutLongStackTrace(error, trace)
|
||||
);
|
||||
}
|
||||
|
||||
// Instruments the inner [Zone] to detect when code is executed in this (or a descendant) zone.
|
||||
// Also runs the onTurnStart hook the first time this zone executes some code in each turn.
|
||||
_innerZone = _outerZone.fork(
|
||||
specification: new ZoneSpecification(
|
||||
run: _innerRun,
|
||||
runUnary: _innerRunUnary,
|
||||
runBinary: _innerRunBinary
|
||||
),
|
||||
zoneValues: {'_name': 'inner'});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -136,47 +124,28 @@ class VmTurnZone {
|
|||
* ```
|
||||
*/
|
||||
dynamic runOutsideAngular(fn()) {
|
||||
return _outerZone.runGuarded(fn);
|
||||
return _outerZone.run(fn);
|
||||
}
|
||||
|
||||
// Executes code in the [_innerZone] & trigger the onTurnStart hook when code is executed for the
|
||||
// first time in a turn.
|
||||
dynamic _innerRun(Zone self, ZoneDelegate parent, Zone zone, fn()) {
|
||||
_maybeStartVmTurn(parent, zone);
|
||||
return parent.run(zone, fn);
|
||||
}
|
||||
|
||||
dynamic _innerRunUnary(Zone self, ZoneDelegate parent, Zone zone, fn(arg), arg) {
|
||||
_maybeStartVmTurn(parent, zone);
|
||||
return parent.runUnary(zone, fn, arg);
|
||||
}
|
||||
|
||||
dynamic _innerRunBinary(Zone self, ZoneDelegate parent, Zone zone, fn(arg1, arg2), arg1, arg2) {
|
||||
_maybeStartVmTurn(parent, zone);
|
||||
return parent.runBinary(zone, fn, arg1, arg2);
|
||||
}
|
||||
|
||||
void _maybeStartVmTurn(ZoneDelegate parent, Zone zone) {
|
||||
void _maybeStartVmTurn(ZoneDelegate parent) {
|
||||
if (!_hasExecutedCodeInInnerZone) {
|
||||
_hasExecutedCodeInInnerZone = true;
|
||||
if (_onTurnStart != null) {
|
||||
_inTurnStart = true;
|
||||
parent.run(zone, _onTurnStart);
|
||||
parent.run(_innerZone, _onTurnStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dynamic _outerRun(Zone self, ZoneDelegate parent, Zone zone, fn()) {
|
||||
dynamic _run(Zone self, ZoneDelegate parent, Zone zone, fn()) {
|
||||
try {
|
||||
_nestedRun++;
|
||||
_maybeStartVmTurn(parent);
|
||||
return parent.run(zone, fn);
|
||||
} finally {
|
||||
_nestedRun--;
|
||||
// If there are no more pending microtasks, we are at the end of a VM turn (or in onTurnStart)
|
||||
// _nestedRun will be 0 at the end of a macrotasks (it could be > 0 when there are nested calls
|
||||
// to _outerRun()).
|
||||
// If there are no more pending microtasks and we are not in a recursive call, this is the end of a turn
|
||||
if (_pendingMicrotasks == 0 && _nestedRun == 0) {
|
||||
if (_onTurnDone != null && !_inTurnStart && _hasExecutedCodeInInnerZone) {
|
||||
if (_onTurnDone != null && _hasExecutedCodeInInnerZone) {
|
||||
// Trigger onTurnDone at the end of a turn if _innerZone has executed some code
|
||||
try {
|
||||
parent.run(_innerZone, _onTurnDone);
|
||||
|
@ -185,15 +154,14 @@ class VmTurnZone {
|
|||
}
|
||||
}
|
||||
}
|
||||
_inTurnStart = false;
|
||||
}
|
||||
}
|
||||
|
||||
dynamic _outerRunUnary(Zone self, ZoneDelegate parent, Zone zone, fn(arg), arg) =>
|
||||
_outerRun(self, parent, zone, () => fn(arg));
|
||||
dynamic _runUnary(Zone self, ZoneDelegate parent, Zone zone, fn(arg), arg) =>
|
||||
_run(self, parent, zone, () => fn(arg));
|
||||
|
||||
dynamic _outerRunBinary(Zone self, ZoneDelegate parent, Zone zone, fn(arg1, arg2), arg1, arg2) =>
|
||||
_outerRun(self, parent, zone, () => fn(arg1, arg2));
|
||||
dynamic _runBinary(Zone self, ZoneDelegate parent, Zone zone, fn(arg1, arg2), arg1, arg2) =>
|
||||
_run(self, parent, zone, () => fn(arg1, arg2));
|
||||
|
||||
void _scheduleMicrotask(Zone self, ZoneDelegate parent, Zone zone, fn) {
|
||||
_pendingMicrotasks++;
|
||||
|
@ -226,16 +194,16 @@ class VmTurnZone {
|
|||
}
|
||||
}
|
||||
|
||||
Zone _createOuterZone(Zone zone, {handleUncaughtError}) {
|
||||
Zone _createInnerZone(Zone zone, {handleUncaughtError}) {
|
||||
return zone.fork(
|
||||
specification: new ZoneSpecification(
|
||||
scheduleMicrotask: _scheduleMicrotask,
|
||||
run: _outerRun,
|
||||
runUnary: _outerRunUnary,
|
||||
runBinary: _outerRunBinary,
|
||||
run: _run,
|
||||
runUnary: _runUnary,
|
||||
runBinary: _runBinary,
|
||||
handleUncaughtError: handleUncaughtError
|
||||
),
|
||||
zoneValues: {'_name': 'outer'}
|
||||
zoneValues: {'_innerZone': true}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,8 +27,6 @@ export class VmTurnZone {
|
|||
_pendingMicrotask: number;
|
||||
// Whether some code has been executed in the _innerZone (& descendants) in the current turn
|
||||
_hasExecutedCodeInInnerZone: boolean;
|
||||
// Whether the onTurnStart hook is executing
|
||||
_inTurnStart: boolean;
|
||||
// run() call depth in _outerZone. 0 at the end of a macrotask
|
||||
// zone.run(() => { // top-level call
|
||||
// zone.run(() => {}); // nested call -> in-turn
|
||||
|
@ -51,11 +49,10 @@ export class VmTurnZone {
|
|||
|
||||
this._pendingMicrotasks = 0;
|
||||
this._hasExecutedCodeInInnerZone = false;
|
||||
this._inTurnStart = false;
|
||||
this._nestedRun = 0;
|
||||
|
||||
this._outerZone = this._createOuterZone(global.zone);
|
||||
this._innerZone = this._createInnerZone(this._outerZone, enableLongStackTrace);
|
||||
this._outerZone = global.zone;
|
||||
this._innerZone = this._createInnerZone(this._outerZone, enableLongStackTrace)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,50 +106,6 @@ export class VmTurnZone {
|
|||
return this._outerZone.run(fn);
|
||||
}
|
||||
|
||||
_createOuterZone(zone) {
|
||||
var vmTurnZone = this;
|
||||
|
||||
return zone.fork({
|
||||
_name: 'outer',
|
||||
'$run': function(parentRun) {
|
||||
return function() {
|
||||
try {
|
||||
vmTurnZone._nestedRun++;
|
||||
return parentRun.apply(this, arguments);
|
||||
} finally {
|
||||
vmTurnZone._nestedRun--;
|
||||
// If there are no more pending microtasks, we are at the end of a VM turn (or in onTurnStart)
|
||||
// _nestedRun will be 0 at the end of a macrotasks (it could be > 0 when there are nested calls
|
||||
// to run()).
|
||||
if (vmTurnZone._pendingMicrotasks == 0 && vmTurnZone._nestedRun == 0) {
|
||||
if (vmTurnZone._onTurnDone && !vmTurnZone._inTurnStart && vmTurnZone._hasExecutedCodeInInnerZone) {
|
||||
try {
|
||||
parentRun.call(vmTurnZone._innerZone, vmTurnZone._onTurnDone);
|
||||
} finally {
|
||||
vmTurnZone._hasExecutedCodeInInnerZone = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
vmTurnZone._inTurnStart = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
'$scheduleMicrotask': function(parentScheduleMicrotask) {
|
||||
return function(fn) {
|
||||
vmTurnZone._pendingMicrotasks++;
|
||||
var microtask = function() {
|
||||
try {
|
||||
fn();
|
||||
} finally {
|
||||
vmTurnZone._pendingMicrotasks--;
|
||||
}
|
||||
};
|
||||
parentScheduleMicrotask.call(this, microtask);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_createInnerZone(zone, enableLongStackTrace) {
|
||||
var vmTurnZone = this;
|
||||
var errorHandling;
|
||||
|
@ -174,28 +127,51 @@ export class VmTurnZone {
|
|||
return zone
|
||||
.fork(errorHandling)
|
||||
.fork({
|
||||
// Executes code in the _innerZone & trigger the onTurnStart hook when code is executed for the
|
||||
// first time in a turn.
|
||||
'$run': function(parentRun) {
|
||||
return function() {
|
||||
vmTurnZone._maybeStartVmTurn()
|
||||
return parentRun.apply(this, arguments)
|
||||
try {
|
||||
vmTurnZone._nestedRun++;
|
||||
if (!vmTurnZone._hasExecutedCodeInInnerZone) {
|
||||
vmTurnZone._hasExecutedCodeInInnerZone = true;
|
||||
if (vmTurnZone._onTurnStart) {
|
||||
parentRun.call(vmTurnZone._innerZone, vmTurnZone._onTurnStart);
|
||||
}
|
||||
}
|
||||
return parentRun.apply(this, arguments);
|
||||
} finally {
|
||||
vmTurnZone._nestedRun--;
|
||||
// If there are no more pending microtasks, we are at the end of a VM turn (or in onTurnStart)
|
||||
// _nestedRun will be 0 at the end of a macrotasks (it could be > 0 when there are nested calls
|
||||
// to run()).
|
||||
if (vmTurnZone._pendingMicrotasks == 0 && vmTurnZone._nestedRun == 0) {
|
||||
if (vmTurnZone._onTurnDone && vmTurnZone._hasExecutedCodeInInnerZone) {
|
||||
try {
|
||||
parentRun.call(vmTurnZone._innerZone, vmTurnZone._onTurnDone);
|
||||
} finally {
|
||||
vmTurnZone._hasExecutedCodeInInnerZone = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
_name: 'inner'
|
||||
'$scheduleMicrotask': function(parentScheduleMicrotask) {
|
||||
return function(fn) {
|
||||
vmTurnZone._pendingMicrotasks++;
|
||||
var microtask = function() {
|
||||
try {
|
||||
fn();
|
||||
} finally {
|
||||
vmTurnZone._pendingMicrotasks--;
|
||||
}
|
||||
};
|
||||
parentScheduleMicrotask.call(this, microtask);
|
||||
}
|
||||
},
|
||||
_innerZone: true
|
||||
});
|
||||
}
|
||||
|
||||
_maybeStartVmTurn(): void {
|
||||
if (!this._hasExecutedCodeInInnerZone) {
|
||||
this._hasExecutedCodeInInnerZone = true;
|
||||
if (this._onTurnStart) {
|
||||
this._inTurnStart = true;
|
||||
this._outerZone.run.call(this._innerZone, this._onTurnStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_onError(zone, e): void {
|
||||
if (isPresent(this._onErrorHandler)) {
|
||||
var trace = [normalizeBlank(e.stack)];
|
||||
|
|
|
@ -226,4 +226,4 @@ String elementText(n) {
|
|||
return DOM.getText(n);
|
||||
}
|
||||
|
||||
String getCurrentZoneName() => Zone.current['_name'];
|
||||
bool isInInnerZone() => Zone.current['_innerZone'] == true;
|
||||
|
|
|
@ -354,6 +354,6 @@ function elementText(n) {
|
|||
return DOM.getText(n);
|
||||
}
|
||||
|
||||
function getCurrentZoneName(): string {
|
||||
return global.zone._name;
|
||||
export function isInInnerZone(): boolean {
|
||||
return global.zone._innerZone === true;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@ import {
|
|||
it,
|
||||
xdescribe,
|
||||
xit,
|
||||
Log
|
||||
Log,
|
||||
isInInnerZone
|
||||
} from 'angular2/test_lib';
|
||||
|
||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||
|
@ -19,10 +20,8 @@ import {BaseException} from 'angular2/src/facade/lang';
|
|||
import {VmTurnZone} from 'angular2/src/core/zone/vm_turn_zone';
|
||||
|
||||
// Schedules a macrotask (using a timer)
|
||||
// The code is executed in the outer zone to properly detect VM turns - in Dart VM turns could not be properly detected
|
||||
// in the root zone because scheduleMicrotask() is not overriden.
|
||||
function macroTask(fn: Function): void {
|
||||
_zone.runOutsideAngular(() => PromiseWrapper.setTimeout(fn, 0));
|
||||
_zone.runOutsideAngular(() => PromiseWrapper.setTimeout(fn, 1));
|
||||
}
|
||||
|
||||
// Schedules a microtasks (using a resolved promise .then())
|
||||
|
@ -145,7 +144,16 @@ export function main() {
|
|||
}
|
||||
|
||||
function commonTests() {
|
||||
describe("run", () => {
|
||||
describe('isInInnerZone', () => {
|
||||
it('should return whether the code executes in the inner zone', () => {
|
||||
expect(isInInnerZone()).toEqual(false);
|
||||
_zone.run(() => {
|
||||
expect(isInInnerZone()).toEqual(true);
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
describe('run', () => {
|
||||
it('should return the body return value from run', inject([AsyncTestCompleter], (async) => {
|
||||
macroTask(() => {
|
||||
expect(_zone.run(() => {
|
||||
|
@ -175,7 +183,7 @@ function commonTests() {
|
|||
macroTask(() => {
|
||||
_zone.run(() => {
|
||||
_log.add('run start');
|
||||
microTask(() => { _log.add('async'); });
|
||||
microTask(_log.fn('async'));
|
||||
_log.add('run end');
|
||||
});
|
||||
});
|
||||
|
@ -194,7 +202,7 @@ function commonTests() {
|
|||
_log.add('start run');
|
||||
_zone.run(() => {
|
||||
_log.add('nested run');
|
||||
microTask(() => _log.add('nested run microtask'));
|
||||
microTask(_log.fn('nested run microtask'));
|
||||
});
|
||||
_log.add('end run');
|
||||
});
|
||||
|
@ -210,15 +218,14 @@ function commonTests() {
|
|||
inject([AsyncTestCompleter], (async) => {
|
||||
macroTask(() => {
|
||||
_zone.run(_log.fn('run1'));
|
||||
});
|
||||
|
||||
macroTask(() => {
|
||||
_zone.run(_log.fn('run2'));
|
||||
});
|
||||
|
||||
macroTask(() => {
|
||||
_zone.run(_log.fn('run3'));
|
||||
});
|
||||
|
||||
macroTask(() => {
|
||||
expect(_log.result()).toEqual('onTurnStart; run1; run2; onTurnDone; onTurnStart; run3; onTurnDone');
|
||||
expect(_log.result()).toEqual('onTurnStart; run1; onTurnDone; onTurnStart; run2; onTurnDone');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
@ -229,23 +236,22 @@ function commonTests() {
|
|||
var b;
|
||||
|
||||
macroTask(() => {
|
||||
_zone.run(() => {
|
||||
a = PromiseWrapper.completer();
|
||||
b = PromiseWrapper.completer();
|
||||
_zone.run(() => {
|
||||
|
||||
_log.add('run start');
|
||||
a.promise.then((_) => {
|
||||
return _log.add('a then');
|
||||
});
|
||||
b.promise.then((_) => {
|
||||
return _log.add('b then');
|
||||
});
|
||||
a.promise.then(_log.fn('a then'));
|
||||
b.promise.then(_log.fn('b then'));
|
||||
});
|
||||
});
|
||||
|
||||
macroTask(() => {
|
||||
_zone.run(() => {
|
||||
a.resolve('a');
|
||||
b.resolve('b');
|
||||
});
|
||||
});
|
||||
|
||||
macroTask(() => {
|
||||
expect(_log.result()).toEqual('onTurnStart; run start; onTurnDone; onTurnStart; a then; b then; onTurnDone');
|
||||
|
@ -276,9 +282,7 @@ function commonTests() {
|
|||
|
||||
macroTask(() => {
|
||||
_zone.run(() => {
|
||||
completer.promise.then((_) => {
|
||||
_log.add('executedMicrotask');
|
||||
});
|
||||
completer.promise.then(_log.fn('executedMicrotask'));
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -302,34 +306,6 @@ function commonTests() {
|
|||
});
|
||||
}));
|
||||
|
||||
it('should not call onTurnStart and onTurnDone when an outer microtask is scheduled from inside angular',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
var completer;
|
||||
|
||||
macroTask(() => {
|
||||
_zone.runOutsideAngular(() => {
|
||||
completer = PromiseWrapper.completer();
|
||||
completer.promise.then((_) => {
|
||||
_log.add('executedMicrotask');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
macroTask(() => {
|
||||
_zone.run(() => {
|
||||
_log.add('scheduling a microtask');
|
||||
completer.resolve(null);
|
||||
});
|
||||
});
|
||||
|
||||
macroTask(() => {
|
||||
expect(_log.result()).toEqual(
|
||||
'onTurnStart; scheduling a microtask; executedMicrotask; onTurnDone'
|
||||
);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should call onTurnStart before executing a microtask scheduled in onTurnDone as well as ' +
|
||||
'onTurnDone after executing the task', inject([AsyncTestCompleter], (async) => {
|
||||
var ran = false;
|
||||
|
@ -347,9 +323,7 @@ function commonTests() {
|
|||
}});
|
||||
|
||||
macroTask(() => {
|
||||
_zone.run(() => {
|
||||
_log.add('run');
|
||||
});
|
||||
_zone.run(_log.fn('run'));
|
||||
});
|
||||
|
||||
macroTask(() => {
|
||||
|
@ -383,7 +357,7 @@ function commonTests() {
|
|||
macroTask(() => {
|
||||
_zone.run(() => {
|
||||
_log.add('scheduleMicrotask');
|
||||
microTask(() => { _log.add('run(executeMicrotask)'); });
|
||||
microTask(_log.fn('run(executeMicrotask)'));
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -409,7 +383,7 @@ function commonTests() {
|
|||
_log.add('onTurnStart(begin)');
|
||||
if (!startPromiseRan) {
|
||||
_log.add('onTurnStart(schedulePromise)');
|
||||
microTask(() => { _log.add('onTurnStart(executePromise)'); });
|
||||
microTask(_log.fn('onTurnStart(executePromise)'));
|
||||
startPromiseRan = true;
|
||||
}
|
||||
_log.add('onTurnStart(end)');
|
||||
|
@ -418,7 +392,7 @@ function commonTests() {
|
|||
_log.add('onTurnDone(begin)');
|
||||
if (!donePromiseRan) {
|
||||
_log.add('onTurnDone(schedulePromise)');
|
||||
microTask(() => { _log.add('onTurnDone(executePromise)'); });
|
||||
microTask(_log.fn('onTurnDone(executePromise)'));
|
||||
donePromiseRan = true;
|
||||
}
|
||||
_log.add('onTurnDone(end)');
|
||||
|
@ -430,12 +404,10 @@ function commonTests() {
|
|||
PromiseWrapper.resolve(null)
|
||||
.then((_) => {
|
||||
_log.add('promise then');
|
||||
PromiseWrapper.resolve(null).then((_) => { _log.add('promise foo'); });
|
||||
PromiseWrapper.resolve(null).then(_log.fn('promise foo'));
|
||||
return PromiseWrapper.resolve(null);
|
||||
})
|
||||
.then((_) => {
|
||||
_log.add('promise bar');
|
||||
});
|
||||
.then(_log.fn('promise bar'));
|
||||
_log.add('run end');
|
||||
});
|
||||
});
|
||||
|
@ -465,8 +437,8 @@ function commonTests() {
|
|||
_zone.run(() => {
|
||||
completerA = PromiseWrapper.completer();
|
||||
completerB = PromiseWrapper.completer();
|
||||
completerA.promise.then((_) => _log.add('a then'));
|
||||
completerB.promise.then((_) => _log.add('b then'));
|
||||
completerA.promise.then(_log.fn('a then'));
|
||||
completerB.promise.then(_log.fn('b then'));
|
||||
_log.add('run start');
|
||||
});
|
||||
});
|
||||
|
@ -503,9 +475,7 @@ function commonTests() {
|
|||
_log.add('run start');
|
||||
microTask(() => {
|
||||
_log.add('async1');
|
||||
microTask(() => {
|
||||
_log.add('async2');
|
||||
});
|
||||
microTask(_log.fn('async2'));
|
||||
});
|
||||
_log.add('run end');
|
||||
});
|
||||
|
@ -521,26 +491,19 @@ function commonTests() {
|
|||
inject([AsyncTestCompleter], (async) => {
|
||||
var promise;
|
||||
|
||||
_zone.initCallbacks({
|
||||
onTurnStart: _log.fn('onTurnStart'),
|
||||
onTurnDone: _log.fn('onTurnDone')
|
||||
});
|
||||
|
||||
macroTask(() => {
|
||||
_zone.runOutsideAngular(() => {
|
||||
promise = PromiseWrapper.resolve(4).then((x) => PromiseWrapper.resolve(x));
|
||||
});
|
||||
|
||||
_zone.run(() => {
|
||||
promise.then((_) => {
|
||||
_log.add('promise then');
|
||||
});
|
||||
promise.then(_log.fn('promise then'));
|
||||
_log.add('zone run');
|
||||
});
|
||||
});
|
||||
|
||||
macroTask(() => {
|
||||
expect(_log.result()).toEqual('onTurnStart; zone run; promise then; onTurnDone');
|
||||
expect(_log.result()).toEqual('onTurnStart; zone run; onTurnDone; onTurnStart; promise then; onTurnDone');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
|
Loading…
Reference in New Issue