0

I have written a custom event bus using BehaviorSubject. It simply executes the subscription passed by a subscriber when a publisher publishes an event. The event bus logic seems to work correctly, but my local variables are not updating correct when the subscription executes. Following is the code:

It's a simple logic that checks if the menu property of map object is false, then it does some work and sets it to true so that the same logic doesn't get executed twice when the subscription is called again.

Issue: For some reason, when the subscription is called second time, the menu property is still false. I understand the js asynchronous behaviour, but things aren't adding up this time for me.

Following is the output:

console.log("1 : " + this.map["menu"]);
console.log("time in milliseconds" + +new Date());

this.eventBus.getEventBusSubscription<Boolean>(this.eventBus.KEY, false)

.subscribe(result => {

    console.log("2 : " + this.map["menu"]);
    console.log("time in milliseconds" + +new Date())

    if (!this.map["menu"]) {
      this.map["menu"] = true

      console.log("3 : " + this.map["menu"]);
      console.log("time in milliseconds" + +new Date());


    }
    console.log("=======END=========")

});
[Log] 1 : false
[Log] time in milliseconds374

[Log] 2 : false
[Log] time in milliseconds678
[Log] 3 : true
[Log] time in milliseconds678
[Log] =======END=========

[Log] 2 : false
[Log] time in milliseconds679
[Log] 3 : true
[Log] time in milliseconds679
[Log] =======END=========

The issue is at 679th milliseconds. When the object property was set to true at 678th millseconds, why is it showing false at 679th millisecond?

Edit: If it would have been an other multithreaded language like Java, I would have assumed that order of execution is NOT guaranteed. The execution at a later time (679) might still be getting older value of this.map["menu"] because threads might not be syncronized. But this being single threaded Javascript, it is guaranteed that execution of code at 679 is done after changing the variable at 678. Nothing changes that fact, like the value of result etc..

Edit: Can BehaviourSubject be the culprit here? Can it be that by some means internal functioning of BehaviourSubject doesn't guarantee order of execution?

Sampgun
  • 2,822
  • 1
  • 21
  • 38
java_doctor_101
  • 3,287
  • 4
  • 46
  • 78
  • can you simulate it in stackblitz? – Hikmat G. Jul 05 '18 at 06:50
  • in `3` `this.menu['menu']` should be `this.map['menu']` – Hikmat G. Jul 05 '18 at 06:59
  • @HikmatGurbanli was a typo.. i will try to do srackblitz – java_doctor_101 Jul 05 '18 at 07:31
  • at the first line `console.log("1 : "+this.map["menu")` should be `console.log("1 : "+this.map["menu"])`. I know that's not the error...but..still... – Sampgun Jul 05 '18 at 07:35
  • Can you print also "RESULT"? Why you don't use result???"?!?!?!?!?!?!? – Sampgun Jul 05 '18 at 07:44
  • @nitinsh99 then how the heck it passes if and prints `true` in 678? it's simply impossible without anything interrupting. – Hikmat G. Jul 05 '18 at 07:53
  • @HikmatGurbanli sorry i didn't get you there. it's false at 678 , so it gets inside the loop, then it is converted to true at point 3. Now the next time subscription is called , it should be true at point 2 since it's a local variable ( at time 679) but it's still false. Why is that? – java_doctor_101 Jul 05 '18 at 17:17
  • @Sampgun sure, i will add result shortly, But how does that matter. It's simple. I changed a local variable to true at 678, it's still showing false at 679. Javascript is single threaded. How is that possible? Moreover, I am doing all of this inside flat arrow function so 'this' is pointing to correct scope – java_doctor_101 Jul 05 '18 at 17:19
  • Where do you make the subscription? it seems like different `this` otherwise it would be impossible – Hikmat G. Jul 05 '18 at 18:34
  • "where do i make subscription" ? when i call subscribe method in above code and pass the flat arrow function result => {} , that's when the subscription is made.. the 'this' is pointing to correct scope because i tried calling a local method using the same 'this' and the method is being called. If 'this' was incorrect, I would get undefined error. how is it impossible, I mean the timing can't be wrong, u see here 678 milliseconds and 679 milliseconds. – java_doctor_101 Jul 05 '18 at 19:11
  • No I think you misunderstood me. I mean is you subscription in some kind of component or class method or function? maybe in the next call you somehow mistakenly create new instance of class or whatever. In that context you have different `this` but the same structure. It can't be time timing issue because statements in subscription callback is atomic, that if there was a parallel running subscription, it would start after all the statements in first subscription complete which would make `map['menu']` true. – Hikmat G. Jul 06 '18 at 05:49
  • You need to create a Stackblitz. – Sampgun Jul 06 '18 at 07:44

1 Answers1

0

You're logging before changing the value...that's why it shows false.

 if (!this.map["menu"]) {
    console.log("3 : " + this.map["menu")
    console.log("time in milliseconds" + new Date().getMilliseconds())

    this.map["menu"] = true
  }

Should be

 if (!this.map["menu"]) {
    this.map["menu"] = true
    console.log("3 : " + this.map["menu")
    console.log("time in milliseconds" + new Date().getMilliseconds())        
  }
Sampgun
  • 2,822
  • 1
  • 21
  • 38