如果导出的模块函数被调用两次则抛出错误
Throw error if exported module function is called twice
我有一个 Node.js 导出函数的模块:
module.exports = function(data){
return {
// return some object
}
};
我想在这里使用单例模式,但不会有太多麻烦。这是一个库,我的库代码可能会多次调用这个函数,但我需要依赖用户来定义代码,所以我不能保证他们会实现一个正确的单例模式.
如果多次调用导出的函数,是否可以使用一个好的模式来抛出错误?
我在想这样的事情:
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 require 函数不会对此有所帮助,但也许吧。
现在我加载这样一个模块的代码是这样的:
const fn = require('./user-defined-module');
const obj = fn.apply(ctx, some_args);
问题是我可以调用代码库中的其他地方
const obj = fn.apply(ctx, some_args);
再次。代码库越来越大,我想快速失败。
在我看来,最好的办法是在第一次调用 fn 时重新定义它。
(1) 我必须将局部变量 fn 设置为
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 内部结构混淆。
将您的库引用替换为函数的 Proxy 可以在较新的 Node 环境中实现相同的目的。然后 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...
我有一个 Node.js 导出函数的模块:
module.exports = function(data){
return {
// return some object
}
};
我想在这里使用单例模式,但不会有太多麻烦。这是一个库,我的库代码可能会多次调用这个函数,但我需要依赖用户来定义代码,所以我不能保证他们会实现一个正确的单例模式.
如果多次调用导出的函数,是否可以使用一个好的模式来抛出错误?
我在想这样的事情:
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 require 函数不会对此有所帮助,但也许吧。
现在我加载这样一个模块的代码是这样的:
const fn = require('./user-defined-module');
const obj = fn.apply(ctx, some_args);
问题是我可以调用代码库中的其他地方
const obj = fn.apply(ctx, some_args);
再次。代码库越来越大,我想快速失败。
在我看来,最好的办法是在第一次调用 fn 时重新定义它。
(1) 我必须将局部变量 fn 设置为
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 内部结构混淆。
将您的库引用替换为函数的 Proxy 可以在较新的 Node 环境中实现相同的目的。然后 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...