當發(fā)生第一次讀取,異步push的數(shù)據(jù)將直接通過emit data傳遞到ondata中,而read函數(shù)中的emit由于無法從緩沖區(qū)讀取數(shù)據(jù)從而不會觸發(fā),同時read返回null導致while循環(huán)也相應停止,此種情況下異步push觸發(fā)data事件后,緊接著的stream.read(0)會繼續(xù)保持流的流動,當dest.write(chunk)返回false,count++執(zhí)行一次并將流暫停,緊接著會繼續(xù)調用一次read,但這次數(shù)據(jù)將被放入緩沖區(qū)且不觸發(fā)data事件,count++依舊只執(zhí)行一次。
場景二流暫停一次后再次流動時,數(shù)據(jù)消耗模式與之前會有所差異,會優(yōu)先消耗緩沖區(qū)數(shù)據(jù)直至為空時回到之前的模式,但這同樣不會導致count++執(zhí)行多次。
與場景一類似,只是每次_read會多次往緩沖區(qū)寫入數(shù)據(jù),最終data事件還是依靠從緩沖區(qū)讀數(shù)據(jù)后觸發(fā)。
同場景二類似,假設在一次_read中有兩次異步push,當?shù)谝粋€異步push執(zhí)行時,data事件觸發(fā)且其中的dest.write(chunk)返回false,導致count++同時流被暫停,等第二個異步push執(zhí)行時,由于流已經(jīng)暫停,數(shù)據(jù)將寫入緩沖區(qū)而不是觸發(fā)data事件,所以count++只執(zhí)行一次。
不管是同步或者異步push,當一次ondata內部將流設置為暫停模式后,flow函數(shù)中while條件state.flowing為false將導致stream.read不再調用,異步的push的emit data判斷條件同樣不再滿足,即目前階段內部不會再有data事件觸發(fā)直到外部再次間接或直接調用read方法。
以上五個場景是為了分析該問題而模擬的,實際只要能理解第五個場景就能明白所有。
小結
文章最終寫出來的內容與我最開始的初衷所偏離,而且自己不知道如何評價這篇文章的好壞,但為了寫這文章花了兩天業(yè)余時間去深入理解stream.Readable卻是非常有收獲的一件事情,更堅定自己在寫文章的路途上可以走的更遠。
PS:猜測為什么有爛電影的存在,可能是因為導演長時間投入的創(chuàng)作會讓他迷失在內部而無法發(fā)現(xiàn)問題,寫文章也是,難以通過閱讀去優(yōu)化費心思寫的文章。
PS:下圖是美團博客的,也許我寫了這么多卻抵不上這張圖,說明方式很重要。
總結
聲明:本網(wǎng)頁內容旨在傳播知識,若有侵權等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com