有人能解释一下howtonode的函数包装习惯用法吗?
Could someone explain a function wrapping idiom from howtonode?
我最近开始使用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
的调用中
那是什么意思?
它拦截对res.writeHead
的调用,添加一些日志记录,然后将调用委托给原始res.writeHead
。
它就像一个超简单的AOP方法拦截。
让我们分解这里发生的事情
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变体的末尾调用它:
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();
}
- 如何使用图表包装函数有条件地格式化谷歌可视化表单元格
- 从原型更改/包装函数
- 我正在尝试使用 html 元素包装函数的返回值
- 将 ajax .done 作用域扩展到包装函数
- 在javascript中需要帮助包装函数并正确处理“this”
- 包装函数后无法读取属性
- 检查是否调用了包装函数
- 从生成器函数中包装co和co-mysql,并从包装函数中让步
- 窗口对象上具有全局变量的包装函数
- 使用removeEventListener删除包装函数回调
- 用JavaScript正确包装函数
- 如何从包装函数返回javascript ajax调用的结果
- 如何包装函数调用,有时做异步调用,使其行为同步
- 为什么UnderscoreJS有很多原生Javascript函数的包装函数?
- Knockout - keyCode属性没有通过包装函数传递
- Highcharts包装函数'
- 中间javascript: ajax请求的包装函数稍后执行主函数
- 是否有一种聪明的方法来访问包装函数中的变量
- Jquery新手在包装函数时遇到问题
- express 4的异步包装函数没有't捕获错误