[英]A function that accepts: a string or a function or two objects
我在Node.js中创建了一个模块,它只公开了一个名为direct
函数,基本上是一个请求路由器(是的,我正在制作我自己的,以便学习)。 但是,我想简化API只使用一个函数。 其他所有东西都被束缚在后,取决于direct
东西。
它现在将接受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
}
如你所见,似乎我很难编写很多东西。 此外,检查效率低,有点长。
http.createServer
的request
和response
对象? 如果你像这样直接实现它可能会更容易:
direct = function(o){
if(o['route'])
DO SOMTHING
}
if(o['fn']){
DO SOMETHING ELSE
}
...
}
总是得到一个能够保持调用者意图的配置对象。
您可以使用基于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
版本。
你几乎要建立一个微型命令解释器,不妨让它看起来像一个。
- 有没有办法检查发送的对象是否是http.createServer的请求和响应对象?
这部分很容易。
来自文档 :
request
是http.ServerRequest
的实例,response
是http.ServerResponse
的实例
所以你的代码看起来像这样,假设你的direct
函数采用命名的形式参数a
和b
(我认为这对于arguments[0]
和arguments[1]
更具可读性):
else if (arguments.length == 2
&& a instanceof http.ServerRequest
&& b instanceof http.ServerResponse)
我想像你一样,如果你只是传递数据,那么有些功能更优雅,更容易使用。
你的代码是正确的,但你太严格了。 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)
}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.