Javascript 角度6设置超时和清除超时错误

Javascript 角度6设置超时和清除超时错误,javascript,angular,typescript,angular6,Javascript,Angular,Typescript,Angular6,我有一个奇怪的问题 我正在使用setTimeout和clearTimeout函数来启动/取消超时。 然而,这有时有效,有时无效。 即使用户触发(点击)事件并运行clearTimeout,有时也会强制玩家抽两张牌 这是密码 //an event that says we must call uno this._hubService.mustCallUno.subscribe(() => { this.mustCallUno = true; this._interva

我有一个奇怪的问题

我正在使用setTimeout和clearTimeout函数来启动/取消超时。 然而,这有时有效,有时无效。 即使用户触发(点击)事件并运行clearTimeout,有时也会强制玩家抽两张牌

这是密码

//an event that says we must call uno 
this._hubService.mustCallUno.subscribe(() => {
      this.mustCallUno = true;
      this._interval = window.setInterval(() => {
        this.countdown -= 100;
      }, 100);
      this._timer = window.setTimeout(() => {
        if (this.mustCallUno) {
            this.drawCard(2);
            this.callUno();
        }
      }, 2000);
    });

// a function player calls from UI to call uno and not draw 2 cards
  callUno() {
    this.mustCallUno = false;
    window.clearTimeout(this._timer);
    window.clearInterval(this._interval);
    this.countdown = 2000;
  }
因此,即使播放器调用callUno()函数,也会执行setTimeout。更糟糕的是,代码在setTimeout
if(this.mustCallUno)
中进行了第一次if检查,这应该是false,因为我们调用callUno()函数
this.mustCallUno=false时只是将其设置为false


我在window.setTimeout之前使用了setTimeout(返回NodeJS.Timer),结果是一样的。

检查
中函数运行的可能性。\u hubService.mustCallUno.subscribe
运行了两次或多次,通常一开始运行时您可能没有预料到。将记录器放入传递给
mustCallUno.subscribe
callUno
的函数中


在这种情况下,可能发生的是
this.\u timer
this.\u interval
将有一个不同的引用,而它们保留的旧引用没有被清除,因为
callUno
没有被调用,或者调用的次数比subscribe中的回调次数少。

您使用的是angular6+,所以我建议您使用反应式编程库,例如


我给你举了个小例子

我可以问一下你为什么不使用rxjs观测仪吗?@Florian我对这个棱角分明的rxjs世界有点陌生。你能用observable发布解决方案并将我链接到一些有用的“入门”页面吗?许多感谢您分享完整的代码!我真的不明白你打算做什么here@tonymarkoc奥基。我将向您展示rxjs解决方案和文档页面的stackblitz。@Aravind其余的代码实际上并不相关。我们通过websocket获得一个事件,玩家必须调用uno(我上面写的第一个函数-订阅),然后用户有2秒钟的时间按下UI中的uno按钮,该按钮将调用
callUno()
函数,该函数本应清除超时,以便玩家不抽2张牌。我还尝试添加
window.cleartimout(此._计时器);窗口.clearInterval(此._时间间隔)作为subscribe方法中的前两行,没有效果。是的,但是它在
callUno
中,对吗?是否保证在下次调用callback to subscribe之前调用
callUno
?它看起来不是一个好的架构,但是放一个简单的记录器应该可以验证它。嗨。问题是我从来没有使用过u你的回答帮助我意识到了这一点,所以我将它标记为正确。很高兴它帮助了你!