接受的函数:一个string或一个函数或两个对象

我在Node.js中创build了一个只显示一个名为direct函数,基本上是一个请求路由器(是的,我正在努力学习)。 不过,我想简化API只使用一个函数。 其他所有东西都会链接在一起,具体取决于direct

现在它将接受3种types的input:一个string(路由)或一个函数(一个callback)或两个对象 – 来自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 } ... } 

总是得到一个configuration对象,将保存调用者的意图。

您可以使用基于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 check抽象成一个函数,然后checker的'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的简单对象replace成支持已知接口的“真实”对象。 这听起来像过度工程,但我可能会停止在good_args版本。

你几乎build立了一个微型的命令解释器,不妨使它看起来像一个。

  • 有没有办法来检查发送的对象是http.createServer的请求和响应对象?

这部分很简单。

从文档 :

requesthttp.ServerRequest一个实例, responsehttp.ServerResponse一个实例

所以你的代码看起来像这样,假设你的direct函数需要命名forms参数ab (我认为这更可读的arguments[0]arguments[1] ):

 else if (arguments.length == 2 && a instanceof http.ServerRequest && b instanceof http.ServerResponse) 

我想和你一样,如果你只是传递给他们的数据,就会有更优雅和更易于使用的function。

你的代码是正确的,但你太严格了。 Javascript是一种弱types的语言。 如果你开始检查每个参数的types,你永远不会结束,一个线路function可能会变得太复杂。 如果你在文档中说函数接收到2个string,那么用户必须传递2个string,如果他决定传递一个布尔函数和一个函数,那么这不是你的问题。

我会写下面的内容:

 var direct = function (param, res){ var type = typeof param; if (type === "string"){ //direct("/") }else if (type === "function"){ //direct(function(){}) }else{ //direct(req, res) } };