Why do we need to defer unregister observer?

I notice when we remove observer, it will be removed after this frame.
Is there any problem if we remove it immediately?

1 Like

It could be a problem because the system can be looping through the list of observables (most likely) and you will update the array while looping it which is always a bad idea :slight_smile:

2 Likes

Thank you for your patience :grinning:
I totally agree with “update the array while looping it which is always a bad idea”.
However, I still want to get to the bottom of it.(forgive my nerdy :crazy_face:)
If I understand correctly, you are talking about:

let arr = [1,2,3,4,5]
for(let i=0; i < arr.length; i++) {
  arr.splice(i, 1)
}
console.log(arr) // [2,4]

I guess there are some ways to solve it if we run this loop in one thread?
For example, we can reverse this loop, but sometimes we want to keep the order so it may not be a good one.

let arr = [1,2,3,4,5]
for(let i=arr.length-1; i >=0 ; i--) {
  arr.splice(i, 1)
}
console.log(arr)// []

A better one can be minus loop count when we splice one element.

let arr = [1,2,3,4,5]
for(let i=0; i < arr.length ; i++) {
  arr.splice(i, 1)
  i--;
}
console.log(arr)// []

Does this method still cause some problems?

I guess in your code, you are not preserving order anymore ?

Can you give me some examples when the last solution cannot preserve order?

I wrote some unit tests for observables and I used a timeout here due to how the actual removal is deferred, but not on other tests (they are copies of babylon.js Observables):
xmachina/subscriptions.lightSwitch.spec.ts at main · brianzinn/xmachina (github.com)

In another application what I want to do is change the callback of an existing observable - I do this at runtime, so it saves me needing to remove and add a new callback:
react-babylonjs/UpdateInstance.ts at master · brianzinn/react-babylonjs (github.com)

I haven’t ran into any issues with current implementation as the observer is marked for removal (and I believe not called anymore) and removed on next event loop. I’d have to look through the code again, but that prevents looping issues in the caller.

edit: to answer your question - there’s no problem to remove it immediately as far as I can tell.

2 Likes