What constitutes a run loop side effect?

Great question! I had an answer originally drafted, but in gathering the steps I realized that my mental model was slightly off.


Time for a code safari :zebra:!

// assume obj here is _something_ :raised_hand: :wave:  
Ember.set(obj, 'foo', 'bar');

When Ember.set runs, the following path is taken:

  1. Ember.set checks if foo were a computed property on obj (assume for now that it isn’t) – here
  2. Ember.set checks if obj.setUnknownProperty exists (assume that it isn’t) – here
  3. Ember.set checks if foo is a dependent key in an observer / computed or is otherwise “watched” (e.g. due to template usage) (assume that it isn’t) – here
  4. Ember.set does obj.foo = 'bar'here
  5. If the value is different that the previous value, Ember.set calls notifyPropertyChange(obj, 'foo')here
  6. notifyPropertyChange checks if the property is being watched, and notifies any observers or computed properties that foo has changed – here
  7. notifyPropertyChange then “marks the object as dirty” – here
  8. markObjectAsDirty grabs the underlying “reference” / “tag” for that object and property then marks it as dirty – here
  9. If there was a tag, markObjectAsDirty calls ensureRunLoop to ensure a runloop is scheduled – here
  10. ensureRunLoop checks if anything has been rendered, and if it has schedules a run loop

Footnotes:

  • markObjectAsDirty is an internal utility function primarily used with Glimmer 2’s reference system

tldr; The basic decision tree for when an Ember.set would schedule work to happen async is:

  • Has anything been rendered yet? If not, then Ember.set currently will not schedule any async.
  • Is the new value being set different than the old value? If not, then nothing is notified or scheduled.
  • Has the object (if an ObjectProxy) or property (for normal objects) been rendered in a template? If not, nothing is scheduled.

If the answers to all of those questions are “yes”, then async will be scheduled…

Phew, sorry about that (it was fun though, huh?)

6 Likes