有人可以解释一个函数从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 )。 ( req , res )对可以通过一系列可以修改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(); }