diff --git a/lib/internal/blob.js b/lib/internal/blob.js index 68071a5f5645e7..e91542681970c1 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,13 @@ const kMaxBatchChunks = 16; async function* createBlobReaderIterable(reader, options = kEmptyObject) { const { getReadError } = options; let wakeup = PromiseWithResolvers(); - reader.setWakeup(wakeup.resolve); + let immediate; + reader.setWakeup(() => { + immediate ??= setImmediate(() => { + immediate = undefined; + wakeup.resolve?.(); + }); + }); try { while (true) { @@ -624,7 +634,6 @@ async function* createBlobReaderIterable(reader, options = kEmptyObject) { if (blocked) { const fin = 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