Node.js重载模块bug

Node.js reloading module bug

本文关键字:bug 模块 重载 js Node      更新时间:2023-09-26

我用这种方式重新加载一个模块:

require('./module.js');             // require the module
delete require.cache('/module.js'); // delete module from cache
require('/module.js');              // re-require the module

但是如果模块包含这样的内容就会出现问题:

setInterval(function(){ 
    console.log('hello!'); 
}, 1000);

每次我重新加载模块一个新的setInterval被调用,但最后一个没有关闭。

是否有任何方法可以了解每个模块的(长)运行函数,以便我可以在再次需要之前停止它们?或者有什么建议吗?

我打开任何疯狂的想法。

这只是一个大胆的猜测,但您可能能够在域中加载模块。

当您完成时,使用domain.dispose()来清除计时器:

dispose方法销毁域,并尽最大努力尝试清理与域关联的所有IO。流被中止、结束、关闭和/或销毁。定时器被清除。不再调用显式绑定的回调。任何错误事件被忽略。

我将简单地为间隔设置一个引用,并公开一个方法,以便像这样停止它:

var interval = setInterval(function () {
    console.log('hello');
}, 1000);
var clearInt = clearInterval(interval);

我不认为你可以挂钩到任何事件,因为你只是删除一个引用。如果它不存在了,它会重新加载。在此之前,请调用clearInt函数。

您可以在主应用程序中创建一个IntervalRegistry:

global.IntervalRegistry = {
    intervals : {},
    register  : function(module, id) {
      if (! this.intervals[module])
      {
        this.intervals[module] = [];
      }
      this.intervals[module].push(id);
    },
    clean     : function(module) {
      for (var i in this.intervals[module])
      {
        var id = this.intervals[module][i];
        clearInterval(id);
      }
      delete this.intervals[module];
    }
  };

在您的模块中,您将注册在那里创建的间隔:

// module.js
IntervalRegistry.register(__filename, setInterval(function() {
  console.log('hello!');
}, 1000));

当需要清理的时候,调用这个:

var modulename = '/full/path/to/module.js'; // !!! see below
IntervalRegistry.clean(modulename);
delete require.cache[modulename];

请记住,模块与它们的完整文件名一起存储在require.cache中。