如何解决“借用”请求对象以将临时数据存储在node.js中有多可怕?
| 从像我这样的node.js新手那里得到这样的代码:require(\'http\').createServer(function( req,resp ) {
var pathname = require(\'url\').parse( req.url ).pathname;
if( req.method === \"POST\" ) {
var postData = \"\";
req.addListener( \"data\",function( postDataChunk ) {
postData += postDataChunk;
});
req.addListener( \"end\",function() {
// do my thing with postData
// and end the response
});
}
}).listen(8888);
...每次有一个“ 1”请求时,都会重新创建发送给侦听器的一组匿名函数。
这似乎(几乎)是必需的,因为节点不会将第二个累加器参数发送给\"data\"
侦听器,也不会将最终结果参数发送给\"end\"
侦听器。因此,匿名函数需要引用postData
变量才能生成结果。
我的喜好是为在服务器请求处理程序外部创建的侦听器命名函数,如下所示:
function data_listener( postDataChunk ) {
this.some_unique_property.accumulator += postDataChunk;
}
function end_listener() {
// do my thing with postData
// and end the response
}
require(\'http\').createServer(function( req,resp ) {
var pathname = require(\'url\').parse( req.url ).pathname;
if( req.method === \"POST\" ) {
req.some_unique_property = {
response: resp,pathname: pathname,accumulator: \"\",};
req.addListener( \"data\",data_listener );
req.addListener( \"end\",end_listener );
}
}).listen(8888);
由于侦听器函数中的this
是request
对象,因此我借用了request
对象来累积发布数据,以便我可以一次创建函数并重用它们。
这是可接受/安全的方法吗?
解决方法
我更喜欢后一种方法而不是许多匿名函数,因为它使组织代码更容易。如果用于处理数据的代码变大,则前者可能会成为内部带有匿名函数的巨型函数,并且难以维护。
使用后者,我可以轻松地将代码分解为单独的模块,以使事情井井有条。如果我使用诸如JSDoc之类的文档,它也使我可以轻松地记录各个处理程序。
我对后者的唯一建议是一些注释,指出ѭ6的含义是什么,这样,读过代码的其他人就不必花太多时间思考它。
, 它可能没有什么问题,但这听起来像是个好主意吗?
匿名函数很便宜。当前的任何JS引擎每秒都可以创建数百万个JS引擎,这比可达到的请求速率高出几个数量级。
, A)我看不出不使用此类函数的原因,我认为这会使事情变得更整洁,无论是匿名的还是这样的,调用堆栈都已经有了另一层,所以使代码程序员可读。
B)这怎么不是路由层的用途?我看不出区别。当然,我更喜欢颠倒我的req方法和我的路径,但是它们实际上是一样的。
, 在我看来,这似乎是过早的优化。我通常处理此类事情的方式大致如下:
require(\'http\').createServer(function( req,res ) {
if( req.method === \"POST\" ) {
var buf = [];
req.on(\'data\',[].push.bind(buf)).on(\'end\',function(){
// do my thing with buf
});
}
}).listen(8888);
顺便说一句,在第二个示例中,您应该剔除require(\'url\')
。
, 如果您真的担心性能,可以编辑http库本身,以根据需要定制自定义继承的请求对象。
显然,http库已经为您提供了重新定义请求类的门,并且它看起来应该像这样:
function MyNewRequest( options,cb ){
http.ClientRequest.call(self,options,cb); //Call the original constructor
this.on(\'data\',this.customData ); //Hook the event,and now we are the object
}
util.inherits(MyNewRequest,http.ClientRequest); //Inherit the original object
MyNewRequest.prototype.customData = function(data){
}
var oldRequest = http.request;
http.request = function( options,cb ){ //Override the original ClientRequest provider
if( options.path == \"/upload\" ) //If it is our special path,return our new object
return new MyNewRequest( options,cb );
return oldRequest( options,cb );
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。