繁体   English   中英

接受以下内容的函数:字符串或函数或两个对象

[英]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.createServerrequestresponse对象?

如果你像这样直接实现它可能会更容易:

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来确保reqresp是正确的东西。 这会让你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的请求和响应对象?

这部分很容易。

来自文档

requesthttp.ServerRequest的实例, responsehttp.ServerResponse的实例

所以你的代码看起来像这样,假设你的direct函数采用命名的形式参数ab (我认为这对于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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM