javascript - Node(Meteor) 中的 setTimeout 内存泄漏

标签 javascript node.js meteor memory-leaks settimeout

当我使用 setTimeout 时出现奇怪的内存泄漏。

我每 15 秒使用一个返回 promise 数组 (Promise.all) 的异步函数调用以下代码,它应该在所有 promise 已解决并完成所有逻辑后 15 秒再次运行。

const schedule = (fn, seconds, runNow = false) => {
  Meteor.setTimeout(() => {
    try {          
      Promise.resolve(fn()).then(()=>{
        schedule(fn, seconds, false)
      }).catch((err)=>{
        log.error(err)
        schedule(fn, seconds, false)
      })
    } catch (e) {
      log.error(e);
    }
  }, runNow ? 0 : seconds * 1000);
};

我已经尝试了 setTimeout 和上面的 Meteor.setTimeout,它们的行为相同,大约一个小时后你可以看到明显的内存泄漏。

值得一提的是,即使我禁用我的代码并且被调用的函数刚刚返回,它仍然会泄漏。

服务器:OSX、Node 9.3、Meteor 1.6

发现很少有其他人使用 setTimeout 发生内存泄漏,但情况不同。

更新 问题是在我不知道的另一项任务中调用了调度函数,并且该任务具有非常繁重的异步代码并且缺少等待,因此它在完成之前被重新调度,并且在一段时间后累加起来。感谢您的所有回答。

最佳答案

如果去掉 try catch 会发生什么?

const schedule = (fn, seconds, runNow = false) => {
  Meteor.setTimeout(() => {
    Promise.resolve()
    .then(fn)
    .then(
      ()=>
        schedule(fn, seconds, false)
    )
    .catch((err)=>{
      log.error(err)
      schedule(fn, seconds, false)
    });
  }, runNow ? 0 : seconds * 1000);
};

我不确定你为什么要尝试并捕获,我假设 fn 是一个可以抛出错误并且不返回 promise 的函数(如果它返回它就不会抛出并拒绝)。

对于可以在 promise 链中使用的 throw 函数,您只需将它们放在 promise 链中。 Promise.resolve(fn()) 不会将其放入链中,但 Promise.resolve().then(fn) 会。

var fn = function(){throw("Not caught in promise")};

var fn = function(){throw("Not caught in promise")};
Promise.resolve().then(fn)
.catch(e=>console.log("============ is caught"));

Promise.resolve(fn())
.catch(e=>console.log("not caught"));

关于javascript - Node(Meteor) 中的 setTimeout 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48080390/

相关文章:

javascript - greensock TweenMax javascript - 杀死循环补间

node.js - 通过 CRON 在设定的时间运行 Node JS 应用程序,还是本质上利用 CRON 运行 24/7 Node 应用程序,哪个效率更高?

javascript - nodejs 快速登录失败

twitter-bootstrap - 如何在 Meteor 1.3 中通过 NPM 使用 Bootstrap ?

meteor - 使用 Meteor 建模和发布基于关注者的提要

node.js - wkhtmltopdf:没有这样的文件或目录

使用 Rhino 将 Javascript 转换为 Java

javascript - 使用 Cypress 在命令行中传递自定义 API key

javascript - 如何访问Inter Json对象对象值

node.js - 在Socket.IO中, 'heartbeat'是可以用来触发其他 Action 的事件吗?