抛出错误,如果导出的模块函数被调用两次

我有一个导出函数的Node.js模块:

module.exports = function(data){ return { // return some object } }; 

我正在寻找在这里使用单身模式,但没有多less额外的大惊小怪。 这是一个库,可能我的库代码可能不止一次地调用这个函数,但是我需要依赖用户来定义代码,所以我不能保证他们会实现一个合适的单例模式。

如果导出的函数被多次调用,是否有一个好的模式可以用来引发错误?

我在想这样的事情:

 const fn = require('./user-defined-module'); const someObject = fn(); // next I want to somehow mark this module as having been loaded 

为了明确,以下是不好的:

 var loaded = null; module.exports = function(data){ if(loaded) { return loaded; } // do some stuff return loaded = { // return some object } }; 

对于一些用例可能已经足够了,但是我正在寻找一些原因来取消标准的单例代码。

我不认为monkeypatching的要求function将有助于这个,但也许。

现在我的代码加载这样一个模块,就像这样:

 const fn = require('./user-defined-module'); const obj = fn.apply(ctx, some_args); 

问题是我可以调用我的代码库中的其他地方

 const obj = fn.apply(ctx, some_args); 

再次。 代码库越来越大,我想快速失败。

在我看来,最好的办法就是重新定义fn,一旦被第一次调用。

(1)我将不得不将局部variablesfn设置为类似的

 fn = function(){ throw 'whoops you messed up' } 

更重要的是(2)

我将不得不将module.exports值设置为

 module.exports = function(){ throw 'whoops you messed up' }; 

希望是有道理的

将一些数据传递给函数库时,或者函数首次被函数库调用时,将函数附加到函数中。 然后保护你的库调用具有该属性的方法:

 function callUserFn() { let fn = require('./user-defined-module'); if ( !fn._calledByMyLibrary ) { fn._calledByMyLibrary = true return fn() } else { throw new Error('Already called') } } 

函数的属性是非常罕见的,所以它不可能与先前存在的任何东西相冲突,并且避免了Node内部的混乱。

用函数的代理replace函数的库引用可以在新的Node环境中实现同样的function。 被called数据可以在代理中设置,而不是在函数中。

 let fn = new Proxy(require('./user-defined-module'), { apply(target, that, args){ if ( fn.called === true ) throw new Error('Already called') fn.called = true return target.apply(that, args) } }) fn('test','one') fn('test','two') // => Error: Already called...