有人可以从howtonode解释一个包装成语的函数吗?
Posted
技术标签:
【中文标题】有人可以从howtonode解释一个包装成语的函数吗?【英文标题】:Could someone explain a function wrapping idiom from howtonode? 【发布时间】:2013-02-24 14:43:57 【问题描述】:我最近开始使用 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 的调用
这是什么意思?
【问题讨论】:
【参考方案1】:它正在拦截对res.writeHead
的调用,添加一些日志记录,然后将调用委托给原始res.writeHead
。
这就像一个超级简单的 AOP 方法拦截。
【讨论】:
谢谢两位!我接受@matt 的回答只是因为它不仅解释了正在发生的事情,而且还引导我进入 AOP,因此现在我有了一些新的材料可以研究。【参考方案2】:让我们分解这里发生的事情
wrapping idiom to hook into the call to writeHead
在标准 express 流程中,接收请求 (req) 并准备响应 (res)。 (req, res) 对可以通过一系列过滤器级联,这些过滤器可以修改 req 并准备 res强>.
在流程中的某一时刻,res 将被视为已准备就绪,可以将响应的标头发送到客户端。将为此目的调用函数 res.writeHead*。
这个函数的原型是function(code, headers),为了记录要发送的headers,你需要在这个时候hook代码并做一个
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 变体的末尾调用它:
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();
【讨论】:
以上是关于有人可以从howtonode解释一个包装成语的函数吗?的主要内容,如果未能解决你的问题,请参考以下文章
成语接龙敢玩嘛:—偷偷学成语,然后惊艳所有人!龙腾虎跃,该你了?评论区见