diff --git a/packages/@ember/-internals/metal/lib/observer.ts b/packages/@ember/-internals/metal/lib/observer.ts index 8ecc57c4f86..4ebe408e114 100644 --- a/packages/@ember/-internals/metal/lib/observer.ts +++ b/packages/@ember/-internals/metal/lib/observer.ts @@ -217,9 +217,9 @@ export function flushSyncObservers() { observer.suspended = true; sendEvent(target, eventName, [target, observer.path]); } finally { - observer.suspended = false; observer.tag = combine(getChainTagsForKey(target, observer.path)); observer.lastRevision = value(observer.tag); + observer.suspended = false; } } }); diff --git a/packages/@ember/-internals/runtime/tests/system/object/observer_test.js b/packages/@ember/-internals/runtime/tests/system/object/observer_test.js index 7efa16d8a2d..6be762ea474 100644 --- a/packages/@ember/-internals/runtime/tests/system/object/observer_test.js +++ b/packages/@ember/-internals/runtime/tests/system/object/observer_test.js @@ -1,5 +1,5 @@ import { run } from '@ember/runloop'; -import { observer, get, set } from '@ember/-internals/metal'; +import { alias, observer, get, set } from '@ember/-internals/metal'; import EmberObject from '../../../lib/system/object'; import { moduleFor, AbstractTestCase, runLoopSettled } from 'internal-test-helpers'; @@ -261,5 +261,36 @@ moduleFor( assert.equal(changed, true, 'child should have been notified of change to path'); } + + async ['@test cannot re-enter observer while it is flushing'](assert) { + let changed = false; + + let Class = EmberObject.extend({ + bar: 0, + + get foo() { + // side effects during creation, setting a value and running through + // sync observers for a second time. + return this.incrementProperty('bar'); + }, + + // Ensures we get `foo` eagerly when attempting to observe it + fooAlias: alias('foo'), + + parentOneTwoDidChange: observer({ + dependentKeys: ['fooAlias'], + fn() { + changed = true; + }, + sync: true, + }), + }); + + let obj = Class.create(); + + obj.notifyPropertyChange('foo'); + + assert.equal(changed, true, 'observer fired successfully'); + } } );