【问题标题】:Why would 'clearTimeout' not work in this scenario?为什么“clearTimeout”在这种情况下不起作用?
【发布时间】:2021-08-05 14:49:37
【问题描述】:

在我的代码中使用“clearTimeout()”阻止“gameTimer”计时器运行时遇到问题。我在这里简化了部分代码,只包含必要的细节。



//This runs when someone connects to my website
io.on('connection', function (socket) {

    let gameTimer;

    //Runs the in-game timer
    function questionCountdown() {
        
        gameTimer = setTimeout(function () {
            //Reveal if the players' answers are right or wrong
            revealAnswer(answeredPlayers, playerData[socket.id].room);

            //Start the countdown for the next question
            countToNextQuestion(playerData[socket.id].room);
        }, 21000)
    }


    //Starts the game
    socket.on('Request Game Start', async function (room) {
        questionCountdown();
    })

    //Runs when a player has answered(ignore the function arguments)
    socket.on('Answered Question', function () {

        //If all users in the room have answered...
        if (answeredPlayers.get(playerData[socket.id].room) == (roomMap.get(playerData[socket.id].room)).length) {

            //Stop the count[THE MAIN ISSUE]
            clearTimeout(gameTimer);

            //Reveal if the players' answers are right or wrong
            revealAnswer(answeredPlayers, playerData[socket.id].room);

            //Start the countdown for the next question
            countToNextQuestion(playerData[socket.id].room);

        }
    })

})

socket.on('Answered Question', function () {中使用的“clearTimeout()”有什么原因不起作用吗?

【问题讨论】:

  • 你有什么问题?请更详细地准确描述发生了什么事件、您观察到发生了什么以及您期望或希望发生什么。
  • 另外,请更正代码的缩进,以便我们更容易看到哪些代码在哪些事件处理程序中。
  • 您确定有时满足您的 if 条件吗?例如,输入一个 console.log 以确保您正在输入该代码。当计时器已经被清除时是否满足?
  • @jfriend00 我已经缩进了一点。当有人回答问题时,我希望计时器停止。但目前它并没有停止,

标签: javascript node.js sockets timeout


【解决方案1】:

clearTimeout() 没有停止之前启动的gameTimer 的可能原因:

  1. socket.on('Answered Question', ...) 事件并未在您认为发生时发生。要么永远不会发生,要么发生得太快。
  2. 条件if (answeredPlayers.get(playerData[socket.id].room) == (roomMap.get(playerData[socket.id].room)).length) 未得到满足或抛出,因此您永远无法到达clearTimeout()
  3. 在停止一个给定用户之前,您为给定用户启动了多个 gameTimer,因此第二个会覆盖第一个的计时器,然后您永远不会停止第一个。
  4. 您的用户离开网页或点击刷新,由于您没有显示正在侦听disconnect 事件,因此您留下了一个永远无法停止的gameTimer 运行。仅供参考,无论是否是您正在查看的当前问题的原因,都应该解决这个问题。
  5. 由于每个 socket.io 连接都有自己的gameTimer,你只是对它是否被停止感到困惑,也许一个gameTimer 被停止了,你只是被以下事实所愚弄还有其他属于不同连接的也在运行。

仅供参考,您可以通过适当的console.log() 语句确定这些是否是原因,然后研究日志。这些时间敏感、事件驱动的问题通常通过详细的日志记录来解决,然后研究日志以准确了解代码中发生了什么和没有发生什么以及以什么顺序发生。

【讨论】:

  • 哇,非常深入。非常感谢。考虑到您所说的一切,我将审查我的代码。
【解决方案2】:

在您的代码中,由于 Timeout 的设置是由事件触发的,因此可能会在未设置 gameTime 的情况下调用 clearTimeoutclearTimeout 也被某个事件触发,如果该事件未触发,则不会清除超时。

问题可能在于您的事件的来源。它们在何时何地被触发?

您也可以测试您的if 语句。在调用clearTimeout 之前添加console.log,看看它是否在你想要的时候运行。

【讨论】:

  • 我知道if (answeredPlayers.get(playerData[socket.id].room) ==(roomMap.get(playerData[socket.id].room)).length) { 有效,因为revealAnswer()countToNextQuestion() 都有效。你在事件方面可能是对的。我将不得不再次检查
猜你喜欢
  • 2017-11-26
  • 2010-12-29
  • 1970-01-01
  • 2011-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多