diff --git a/lib/internal/blob.js b/lib/internal/blob.js index 68071a5f5645e7..e85438f5d5704b 100644 --- a/lib/internal/blob.js +++ b/lib/internal/blob.js @@ -475,9 +475,13 @@ function createBlobReaderStream(reader) { this.pendingPulls = []; // Lazily register a wakeup callback that the C++ side can invoke // when new data is available after a STATUS_BLOCK. + let immediate; this.wakeup = () => { if (this.pendingPulls.length > 0) { - this.readNext(c); + immediate ??= setImmediate(() => { + immediate = undefined; + this.readNext(c); + }); } }; }, @@ -577,7 +581,15 @@ const kMaxBatchChunks = 16; async function* createBlobReaderIterable(reader, options = kEmptyObject) { const { getReadError } = options; let wakeup = PromiseWithResolvers(); - reader.setWakeup(wakeup.resolve); + let immediate; + let fin = false; + reader.setWakeup((setfin) => { + fin ||= setfin; + immediate ??= setImmediate(() => { + immediate = undefined; + wakeup.resolve?.(); + }); + }); try { while (true) { @@ -622,9 +634,8 @@ async function* createBlobReaderIterable(reader, options = kEmptyObject) { if (error) throw error; if (blocked) { - const fin = await wakeup.promise; + await wakeup.promise; wakeup = PromiseWithResolvers(); - reader.setWakeup(wakeup.resolve); // If the wakeup was triggered by FIN (EndReadable), the DataQueue // is capped. Continue the loop to pull again -- the next pull will // return EOS. Without this, a race between the data notification