【问题标题】:I am using a recursive timeout function in Nodejs but it isn't working as expected我在 Nodejs 中使用递归超时函数,但它没有按预期工作
【发布时间】:2021-08-01 23:34:28
【问题描述】:

我有一个从 mongo db 获取用户数的函数:

let totalOnlinePlayers = 0;
async function GetTotalOnlinePlayers() {
    totalOnlinePlayers = await db.GetTotalOnlinePlayers();
    setTimeout(GetTotalOnlinePlayers, constants.timeToUpdateOnlineCount);
}
let x = GetTotalOnlinePlayers();

在db中,函数如下:

let GetTotalOnlinePlayers = async function () {
    return User.collection.estimatedDocumentCount();
};

它按预期工作。

但我使用的是在另一个 vps 上运行的 mongo 服务器,当我通过停止 15-20 秒以上来重新启动 mongo 服务器时,超时不再执行。

当我重新启动节点服务器时,它又可以正常工作了 但问题又是,我在我的节点服务器中使用套接字并重新启动它会断开我游戏中的玩家并且有时会弄乱我的游戏逻辑。

我可以避免重新启动 mongoserver,但我很好奇是什么导致了这个问题。

【问题讨论】:

    标签: node.js mongodb socket.io settimeout


    【解决方案1】:

    当您的数据库不可用时,您的 .estimatedDocumentCount() 方法可能会引发异常。

    尝试像这样重构

    let totalOnlinePlayers = 0;
    async function GetTotalOnlinePlayers() {
      while(true) {
        try {
          totalOnlinePlayers = await User.collection.estimatedDocumentCount();
        } catch (e) {
          console.log ('error in await .estimatedDocumentCount()', e, 'retrying')
        }
        await new Promise(r => setTimeout(r, constants.timeToUpdateOnlineCount)); 
      }
    } 
    

    然后,这是一个循环,具有简单的逻辑,在您的异步函数中轮询数据库并等待。这个

    await new Promise(r => setTimeout(r, delayInMilliseconds)); 
    

    是您在异步 javascript 中拼写 await sleep(delayInMilliseconds) 的方式。以这种方式构建代码使流程更易于理解。

    【讨论】:

    • 没有安静地遵循这一步,而是使用了 setInterval 而不是 setTimeout 并且在重新启动时也能正常工作
    猜你喜欢
    • 2016-04-08
    • 2014-08-20
    • 1970-01-01
    • 1970-01-01
    • 2017-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多