有人可以解释一个函数从howtonode包装成语吗?

我最近开始使用node.js,express&mongodb。 由于快递使用连接提供中间件支持,我开始阅读中间件和连接。

我在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的调用,添加一些日志logging,然后将调用委托给原始的res.writeHead

这就像一个超级简单的方法截取AOP。

让我们分解这里发生的事情

 wrapping idiom to hook into the call to writeHead 

在标准的快递stream程中,收到请求( req )并准备响应( res )。 ( reqres )对可以通过一系列可以修改req并准备res的filter级联。

在stream程中的某一点, 资源将被视为已经做好充分的准备,可以将响应的标题发送给客户端。 函数res.writeHead *将被调用。

这个函数的原型是函数(代码,头文件) ,为了logging将要发送的头文件,你需要在这个时候钩住代码,并做一个

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

在某种程度上,如果代码中的最初函数是

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

你想用a代替这个代码

 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代码已经丢失,不会被调用。 因此,头文件将被logging,但不会发送到客户端!

你需要一种方法来“记住”原来的代码,并在你写完头部variables的时候调用它:

 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(); }