【问题标题】:Incorrect value in observable subscribe function可观察订阅函数中的值不正确
【发布时间】:2026-01-24 23:00:01
【问题描述】:

我使用 BehaviorSubject 编写了一个自定义事件总线。它只是在发布者发布事件时执行订阅者传递的订阅。事件总线逻辑似乎工作正常,但订阅执行时我的局部变量没有正确更新。以下是代码:

这是一个简单的逻辑,它检查地图对象的菜单属性是否为假,然后它会做一些工作并将其设置为真,这样当再次调用订阅时,相同的逻辑就不会被执行两次。

问题: 由于某种原因,第二次调用订阅时,菜单属性仍然为 false。我了解 js 的异步行为,但这次对我来说并没有加起来。

以下是输出:

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=========

问题出现在第 679 毫秒。当对象属性在第 678 毫秒设置为 true 时,为什么在第 679 毫秒显示为 false?

编辑:如果它是像 Java 这样的其他多线程语言,我会假设不保证执行顺序。稍后的执行(679)可能仍然会获得 this.map["menu"] 的旧值,因为线程可能未同步。但这是单线程 Javascript,可以保证在 678 处更改变量后执行 679 处的代码。没有什么能改变这一事实,例如结果的值等。

编辑:BehaviourSubject 是这里的罪魁祸首吗?难道BehaviourSubject的内部功能通过某种方式不能保证执行顺序?

【问题讨论】:

  • 你能在stackblitz中模拟它吗?
  • 3 this.menu['menu'] 应该是this.map['menu']
  • @HikmatGurbanli 打错了.. 我会尝试做 srackblitz
  • 第一行的console.log("1 : "+this.map["menu") 应该是console.log("1 : "+this.map["menu"])。我知道那不是错误……但是……仍然……
  • 你还能打印“RESULT”吗?为什么你不使用结果???“?!?!?!?!?!?!?

标签: javascript asynchronous observable behaviorsubject subject-observer


【解决方案1】:

您在更改值之前记录...这就是它显示错误的原因。

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

    this.map["menu"] = true
  }

应该是

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

【讨论】:

  • 感谢您对此进行调查。这不是这里的问题,这是复制时出错。我更新了问题。
  • 我通过使用 sn-p 功能改进了您的问题。
  • 并修正了你所有的错别字
最近更新 更多