1

Node.jsでdirect、基本的にリクエストルーターという名前の1つの関数のみを公開するモジュールを作成しています(はい、学習するために独自に作成しています)。ただし、APIを単純化して1つの関数だけを使用したいと思います。何が行われたかに応じて、他のすべては後に連鎖しdirectます。

今のところ、次の3種類の入力を受け入れます。文字列(ルート)または関数(コールバック)または2つのオブジェクト-からの要求オブジェクトと応答オブジェクト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
}

ご覧のとおり、私は多くのものをハードコーディングしているようです。また、チェックは非効率的で少し長いです。

  • 与えられた基準に従って引数をフィルタリングする効率的な方法は何ですか?
  • 送信されたオブジェクトがrequestresponseのオブジェクトであったかどうかを確認する方法はありhttp.createServerますか?
4

4 に答える 4

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を確認できます。これにより、次のような外観になります。reqrespdirect

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バージョンにとどまるでしょう.

ミニチュアのコマンド インタープリターをほとんど構築しているので、それを 1 つのように見せることもできます。

于 2012-11-13T07:52:41.250 に答える
1

このように直接実装すると、より簡単になる可能性があります。

direct = function(o){

  if(o['route'])
    DO SOMTHING
  }

  if(o['fn']){
    DO SOMETHING ELSE
  }
  ...
}

呼び出し元の意図を保持する構成オブジェクトを常に取得します。

于 2012-11-13T07:28:49.753 に答える
1
  • 送信されたオブジェクトが http.createServer の要求オブジェクトと応答オブジェクトであるかどうかを確認する方法はありますか?

この部分は簡単です。

ドキュメントから:

requestのインスタンスでhttp.ServerRequestありresponse、のインスタンスですhttp.ServerResponse

directしたがって、関数が名前付きの仮パラメーターaを受け取ると仮定すると、コードは次のようになります(これはandbより読みやすいと思います)。arguments[0]arguments[1]

else if (arguments.length == 2
        && a instanceof http.ServerRequest
        && b instanceof http.ServerResponse)
于 2012-11-14T08:27:02.693 に答える
0

あなたのように、データを渡すだけで、よりエレガントで使いやすい関数があると思います。

あなたのコードは正しいですが、厳しすぎます。Javascript は型付けが弱い言語です。各パラメーターの型をチェックし始めると、終わりがなく、1 行の関数が複雑になりすぎる可能性があります。関数が 2 つの文字列を受け取るとドキュメントで言う場合、ユーザーは 2 つの文字列を渡す必要があります。1 つのブール値と 1 つの関数を渡すことにした場合、それは問題ではありません。

次のように書きます。

var direct = function (param, res){
  var type = typeof param;
  if (type === "string"){
    //direct("/")
  }else if (type === "function"){
    //direct(function(){})
  }else{
    //direct(req, res)
  }
};
于 2012-11-13T13:04:48.223 に答える