簡體   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