我有一個從檔案創建的流,我打算稍后使用它。但是,我注意到如果我等待任何異步代碼運行,即使它與我的流完全無關,它也會導致流被讀取。為什么會發生這種情況?
代碼在服務器端。
const data = fs.createReadStream(filePath);
console.log(data.bytesRead); // output: 0
await new Promise(r => setTimeout(r, 2000));
console.log(data.bytesRead); // output: 65536
uj5u.com熱心網友回復:
此解釋適用于節點 v14 及之前...節點 v15 中的行為已更改,當我在 v16 中對其進行測驗時,這兩個data.bytesRead值都會顯示0。
在為檔案fs.createReadStream()呼叫異步之后fs.open(),它然后讀取檔案的第一個塊,以便在流開始流動時它可用于流式傳輸。這是內部預緩沖。這樣做很可能是因為它提高了性能。如果您假設閱讀器將讀取整個流(或大部分),那么您最好在檔案打開成功后立即獲取內容的第一個緩沖區,即使流尚未流動或什至如果呼叫者沒有被手動呼叫來讀取一些位元組。
因為讀取是異步的,所以直到您造成的延遲await(讀取在您的 期間完成await)之后才會顯示結果。所以,這就是為什么await允許您看到值變化的原因。
如果您想使用 跟蹤代碼fs.createReadStream(),您可以在除錯器中逐步執行并準確觀察它的作用。該構造ReadStream函式中的代碼結構在 v14 和最新版本之間發生了很大變化,因此如果將您在 Github 源代碼中看到的內容與在除錯器中單步執行的內容進行比較,如果兩者版本不同,您可能會感到困惑(那發生在我身上)。盡管最近版本的實作有所改變,但想法是相同的(預取第一塊內容)。
首先,它呼叫ReadStream建構式。然后,作為其中的一部分,它打開檔案,并在檔案打開成功后,將檔案的第一個塊讀入其當前緩沖區。
看來這個Github 問題似乎是負責更改 readStream 以便它不再自動開始讀取,并且相應的代碼更改看起來像是進入了 v15。
在此處的 v16 ReadStream 代碼中,您現在可以看到檔案的打開位置(在新_construct方法中),并且在打開檔案后,不再有任何代碼來預取檔案的第一個塊。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/346349.html
上一篇:嘗試從已知的映射函式構造陣列
