2015-08-09 21 views
1

節點的文件表明,對於讀取數據流的新最好的辦法如下:在節點中讀取流的新方法是否會導致阻塞?

var readable = getReadableStreamSomehow(); 
readable.on('readable', function() { 
    var chunk; 
    while (null !== (chunk = readable.read())) { 
    console.log('got %d bytes of data', chunk.length); 
    } 
}); 

對我來說這似乎導致阻塞while循環。這意味着,如果節點通過讀取和發送文件來響應http請求,則在進行塊讀取之前,該進程將不得不阻止。

這不是阻止IO哪個node.js試圖避免?

回答

2

這裏需要注意的重要一點是,它不會阻塞,因爲它正在等待更多輸入到達流中。它只是檢索流的內部緩衝區的當前內容。由於沒有等待I/O,這種循環會很快完成。

+0

因此,如果這是某種大文件上傳,在讀取文件時如何輕鬆防止阻塞很長一段時間。我知道'read'可以有一個大小的參數,但我不確定合理的大小是多少。 – Startec

+2

大多數流的內部緩衝區的默認高水位標記是16KB。之後,背壓開始並向上遊發出信號以停止發送數據。由於操作系統在有數據可用時通知節點,因此不會阻塞,這會導致流緩衝區。然後按照示例中所示讀取該緩衝區的當前內容是非阻塞的,因爲該數據只在內存中。如果你想顯式地請求一定數量的字節,'read(n)'實際上是非常有用的。 – mscdex

0

流可以是同步的也可以是異步的。如果可讀流同步推送內部緩衝區中的數據,那麼您將獲得一個同步流。是的,在這種情況下,如果它同步推送大量數據,節點的事件循環將無法運行,直到所有數據被推送。有趣的是,如果你甚至刪除readble回調中的while循環,流模塊internally calls a while loop一次並繼續運行,直到讀取所有推送的數據。

但是,對於異步IO操作(例如httpfs模塊),它們會在緩衝區中異步推送數據。因此,while循環只在數據被緩存到緩衝區時運行,並且只要您讀完整個緩衝區就停止。