我正在Node.js中创建一个模块,它只公开一个名为direct
的函数,基本上是一个请求路由器(是的,我正在制作我自己的,以便学习)。但是,我想简化API只使用一个函数。其他所有内容都会被锁定,具体取决于direct
- ed。
现在将接受3种类型的输入:字符串(路由)或函数(回调)或两个对象 - 来自http.createServer
的请求和响应对象:
direct('/'); //pass a route string
direct(function(){}); //pass callback
direct(req,res); //pass the request and response
这些内部因素让我担心。目前我在做:
//if only one,
if(arguments.length === 1) {
if( typeof arguments[0] === 'string') {
//add to routes
} else if( typeof arguments[0] === 'function') {
//add to callbacks
} else {
//return an error
}
} else if(arguments.length === 2 && ...check if both are typeof object, not null, not instance of array...) {
//extremely long check if both are objects
//planning to extract the check as a function
} else {
//return an error object
}
如你所见,似乎我很难编写很多东西。此外,检查效率低,有点长。
request
的{{1}}和response
个对象?答案 0 :(得分:1)
如果你这样直接实现它可能会更容易:
direct = function(o){
if(o['route'])
DO SOMTHING
}
if(o['fn']){
DO SOMETHING ELSE
}
...
}
总是会得到一个能够保持调用者意图的配置对象。
答案 1 :(得分:1)
您可以使用基于typeof
的查找表:
var handlers = {
'string': { n: 1, fn: function(route) { ... } },
'function': { n: 1, fn: function(callback) { ... } },
'object': { n: 2, fn: function(req, resp) { ... } }
};
然后:
var handler = handlers[typeof arguments[0]];
if(!handler) {
// throw a hissy fit and bail out
}
if(arguments.length != handler.n) {
// throw a different hissy fit and bail out.
}
return handler.fn.apply(null, arguments);
你也可以抛弃n
并使用处理函数的length
属性:
var handlers = {
'string': function(route) { ... },
'function': function(callback) { ... },
'object': function(req, resp) { ... }
};
var handler = handlers[typeof arguments[0]];
if(!handler) {
// throw a hissy fit and bail out
}
if(arguments.length != handler.length) {
// throw a different hissy fit and bail out.
}
return handler.apply(null, arguments);
您可以进一步将handler.n
检查抽象为一个函数,然后检查器的'object'
版本可以使用instanceof
来确保req
和resp
是正确的事情。这会让你的direct
看起来像这样:
var handlers = {
'string': {
good_args: function(arguments) { ... },
fn: function(route) { ... }
},
//...
};
var handler = handlers[typeof arguments[0]];
if(!handler) {
// throw a hissy fit and bail out
}
if(!handlers.check_args(arguments)) {
// throw a different hissy fit and bail out.
}
return handler.fn.apply(null, arguments);
如果您需要处理更多复杂性和可变性,那么您可以将handlers
中的简单对象替换为支持已知接口的“真实”对象。虽然闻起来像过度工程,我可能会停留在good_args
版本。
你正在构建一个微型命令解释器,不妨让它看起来像一个。
答案 2 :(得分:1)
- 有没有办法检查发送的对象是否是http.createServer的请求和响应对象?
这部分很容易。
来自docs:
request
是http.ServerRequest
的一个实例,response
是http.ServerResponse
的实例
所以你的代码看起来像这样,假设你的direct
函数采用命名的形式参数a
和b
(我认为arguments[0]
和{arguments[1]
更具可读性{1}}):
else if (arguments.length == 2
&& a instanceof http.ServerRequest
&& b instanceof http.ServerResponse)
答案 3 :(得分:0)
我想和你一样,如果你只是传递数据,那么有些功能更优雅,更容易使用。
你的代码是正确的,但你太严格了。 Javascript是一种弱类型语言。如果您开始检查每个参数的类型,您将永远不会结束,并且一行函数可能变得过于复杂。如果你在你的文档中说该函数接收2个字符串,那么用户必须传递2个字符串,如果他决定传递一个布尔值和一个函数,那不是你的问题。
我会写下以下内容:
var direct = function (param, res){
var type = typeof param;
if (type === "string"){
//direct("/")
}else if (type === "function"){
//direct(function(){})
}else{
//direct(req, res)
}
};