首页 > 解决方案 > 我在 Nodejs 中使用递归超时函数,但它没有按预期工作

问题描述

我有一个从 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 服务器,当我通过停止 mongo 服务器超过 15-20 秒来重新启动它时,超时不再执行。

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

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

标签: node.jsmongodbsocket.iosettimeout

解决方案


当您的数据库不可用时,您的.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)); 

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


推荐阅读