Change detection with Observable vs Immutable

后端 未结 2 1246
盖世英雄少女心
盖世英雄少女心 2021-02-05 13:37

So I read this article about Angular 2 change detection, but after reading it I have got more confused, so I started reading some of the comments which led to more confusion.

相关标签:
2条回答
  • 2021-02-05 14:15

    I don't get it how Observables are quite different from Immutables and in this specific case of the Todo app, which approach is better?

    Imagine that you have a tree of nodes, and each node has a bit that says "I may have changed". With Observable, we are talking about events getting emitted; the event is dispatched up the tree. In other words:

    • Todo_ChangeDetector would be flagged,
    • then walking up the tree, Todos_ChangeDetector would be flagged,
    • then walking up the tree, App_ChangeDetector would be flagged,
    • then the normal change detection kicks in.

    Imagine you have 2 todo lists:

    1. a grocery list.
    2. a list of meetings (work?) for the day.

    Which grocery list is active you are currently showing would be the Observable; e.g. a dropdown, nav pills, etc. All the todo items under those 2 lists could be Immutable; e.g. you are not the meeting organizer and cannot change the meetings.

    0 讨论(0)
  • 2021-02-05 14:29

    So, like we are 5 year olds from now on.

    This is JohnCmp. John is a component that accepts two inputs, a name: {first: 'John', last: 'Smith'} and an age: 20.

    What happens if name is mutable? Well, someone could pass it to John and hold a reference to it. So that John, and ANY number of other objects or services can hold a reference to that name object. This means they can change it, say doing name.last = 'foo'. And John's name changes now, but he didn't receive a new name. He still has a reference to that name object, but it mutated.

    If we want to detect this, we have to aggressively check name, name.first, name.last, and so on with every property of every object we pass around. How much easier would it be to do name === newName and just compare references, hey? If name is immutable, we don't need to go crazy and check every property, we can check references and know if an object is changed quickly.

    Ok, now, imagine nobody holds a reference to John's name object. So if they want to give him a new name, they must pass in a NEW name object. Then John changes only when his input changes. This is what is meant here:

    If a component depends only on its input properties, and they are immutable, then this component can change if and only if one of its input properties changes. Therefore, we can skip the component’s subtree in the change detection tree until such an event occurs.

    Alright, so that's the basic case right? Now we don't have to worry about checking every property, we just check that references haven't changed. Much improved! BUT objects can be large. So a people array is an immutable Array of Johns, which are immutable, of names that are also immutable. So in order to change John's name. you need to produce a new name, and a new John, and a new people array.

    So they all change, the whole tree needs to be traversed. So that's O(n). Hence this little comment:

    If you have a tree of components with immutable bindings, a change has to go through all the components starting from the root.

    BUT

    This is not the case when dealing with observables.

    Why tho?

    Observables emit events. They don't need to change everything like immutables, they just need to emit a change event. So in his example, you don't have an immutable "array" that you need to recreate and therefore re-evaluate all the changes up the tree. Now you have a people observable, that triggers events when it changes. And John receives an observable as well.

    So you can just trigger an event in John telling him that his name changed, WITHOUT triggering an event in people or things of the sort. Avoiding you to re scan everything for changes, thus reducing complexity to O(log n), as per this quote:

    As you can see, here the Todos component has only a reference to an observable of an array of todos. So it cannot see the changes in individual todos.

    (emphasis mine).

    Hope this helps.

    0 讨论(0)
提交回复
热议问题