2

最近、node.js、express、mongodb を使い始めました。Express は connect を使用してミドルウェア サポートを提供するため、ミドルウェアと接続について読み始めました。

howtonode.orgで次の例を見つけました。

return function logItHandle(req, res, next) {
 var writeHead = res.writeHead; // Store the original function

 counter++;

 // Log the incoming request
 console.log("Request " + counter + " " + req.method + " " + req.url);

 // Wrap writeHead to hook into the exit path through the layers.
 res.writeHead = function (code, headers) {
   res.writeHead = writeHead; // Put the original back

   // Log the outgoing response
   console.log("Response " + counter + " " + code + " " + JSON.stringify(headers));

   res.writeHead(code, headers); // Call the original
 };

 // Pass through to the next layer
 next(); 
};

誰かがこの閉鎖で何が起こっているのか説明してもらえますか? 著者はそれを

writeHead の呼び出しにフックするラッピング イディオム

どういう意味ですか?

4

2 に答える 2

3

への呼び出しをインターセプトしres.writeHead、ロギングを追加してから、元のへの呼び出しを委任しますres.writeHead

これは、メソッドインターセプトのためのAOPの非常に単純なテイクのようなものです。

于 2013-03-08T22:33:18.430 に答える
1

ここで起こっていることを分解しましょう

wrapping idiom to hook into the call to writeHead

通常のExpressフローでは、リクエスト ( req ) を受け取り、レスポンス ( res ) を準備します。( req , res ) ペアは、 reqを変更してresを準備できる一連のフィルターを介してカスケードできます。

フローのある時点で、resは、応答のヘッダーをクライアントに送信できるように十分に準備されていると見なされます。関数res.writeHead * がその目的で呼び出されます。

この関数のプロトタイプはfunction (code, headers)です。送信されるヘッダーをログに記録するには、この瞬間にコードをフックして、

console.log("Response " + code + " " + JSON.stringify(headers));

ある意味で、コード内の元の関数が

res.writeHead = function(code, headers) {
    // original code
}

このコードを

res.writeHead = function(code, headers) {
    console.log("Response " + code + " " + JSON.stringify(headers));
    // original code
}

ある意味では、writeHead 関数の先頭にコードのスニペットを「挿入」する必要があります。

しかし、元の writeHead コードを変更しようとしてはいけません。なぜなら、このコードがどこに書かれているかさえわからず、探したくないからです。したがって、この関数をハイジャックしたい場合: コードの一部が res.writeHead を呼び出す場合、代わりに関数を呼び出す必要があります。

これへの方法は単純です

return function logItHandle(req, res, next) {
   res.writeHead = function (code, headers) {
       console.log("Response " + code + " " + JSON.stringify(headers));
   }
   next(); 
}

ただし、これだけを行うと、元の writeHead コードが失われ、呼び出されないため、少し問題が発生します。したがって、ヘッダーはログに記録されますが、クライアントには送信されません!

元のコードを「記憶」し、writeHead variant の最後に呼び出す方法が必要です。

return function logItHandle(req, res, next) {

   // save the original writeHead function so that it can be referenced in the closure
   var originalWriteHead = res.writeHead; 

   res.writeHead = function (code, headers) {

       // log the response headers
       console.log("Response " + code + " " + JSON.stringify(headers));

       // make as if our hook never existed in the flow
       res.writeHead = originalWriteHead ;

       // call the original writeHead because otherwise the external code
       // called our implementation of writeHead instead of the original code
       res.writeHead(code, headers);

   }
   next(); 
}
于 2013-03-09T09:46:12.910 に答える