繁体   English   中英

请求回调在node.js中是一种不好的做法吗?

[英]Are callbacks for requests a bad practice in node.js?

假设您要下载图片或文件,这将是互联网教会您继续前进的第一种方式:

request(url, function(err, res, body) {
    fs.writeFile(filename, body);
});

但这不是在body累积所有数据,填满内存吗? pipe会更有效吗?

request(url).pipe(fs.createWriteStream(filename));

还是以类似的方式在内部进行处理,无论如何都要缓冲流,从而使此无关紧要?

此外,如果我要使用回调而不是 body (因为您仍然可以使用pipe ),那么是否仍将填充此内存缓冲区?

我问是因为第一种(回调)方法允许我链接下载,而不是并行启动下载(*),但是我不想填充一个我都不用的缓冲区。 因此,如果我不想诉诸异步之类的东西只是为了使用队列来防止这种情况,就需要回调。

(*)这很不好,因为如果您在完成文件之前仅request太多文件,则request的异步性质将导致节点因过量事件和内存丢失而窒息而死。 首先,您将获得以下内容:

"possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit."

并且当扩展它时,500个管道请求将填满您的内存并崩溃节点。 这就是为什么需要回调而不是管道的原因,因此您知道何时启动下一个文件。

但这不将体内的所有数据都累积到内存中吗?

是的,许多操作(例如您的第一个片段将数据缓存到内存中进行处理)。 是的,这会使用内存,但这至少很方便,有时甚至需要,这取决于您打算如何处理该数据。 如果要加载HTTP响应并将主体解析为JSON,这几乎总是通过缓冲来完成,尽管流解析器可以实现,但它要复杂得多,通常是不必要的。 大多数JSON数据不够大,因此流媒体是一个大赢家。

还是在内部以类似方式处理此问题,从而使其无关紧要?

不可以,作为字符串为您提供完整数据的API使用缓冲而不是流式传输。

但是,多媒体数据是的,您不能实际将其缓冲到内存中,因此流式传输更为合适。 同样,数据往往是不透明的(您不解析或处理它),这对于流式传输也很有用。

只要情况允许,流式传输就很好了,但这并不意味着缓冲必定有问题。 事实是缓冲是大多数情况下大多数时间是如何工作的。 从总体上看,流式传输一次仅缓冲1个块,并将它们限制在可用资源范围内的一定大小限制内。 如果要处理数据,则某些时候某些部分需要通过内存。

因为如果您仅一个一个地请求太多文件,那么请求的异步性质将导致节点因过量事件和内存丢失而窒息而死。

不确定确切要在这里说/要问的是什么,但是是的,编写有效的程序需要考虑资源和效率。

另请参见hyperquest README中有关流/池化的子堆栈设置

我想出了一个解决方案,使有关内存的问题变得无关紧要(尽管我仍然很好奇)。

如果我要使用回调而不是 body (因为您仍然可以使用pipe ),那么此内存缓冲区是否仍会被填充?

您不需要来自request()callback即可知道请求何时完成。 stream “结束”时, pipe()将自行关闭。 关闭发出一个事件,可以监听:

request(url).pipe(fs.createWriteStream(filename)).on('close', function(){           
    next();
});

现在,您可以将所有请求排队,并一一下载文件。

当然,您可以使用async.queueasync.queue使用8个并行请求来async.queue ,但是如果您要做的只是用一个简单的脚本获取一些文件,那么async可能会过大。

此外,无论如何,您都不希望为多用户系统上的一个窍门最大化系统资源。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM