From f37825660c7d485d2a34dc64e045f7923c905d7d Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Wed, 22 Mar 2023 06:46:58 +0200 Subject: [PATCH] stream: dont wait for next item in take when finished PR-URL: https://github.com/nodejs/node/pull/47132 Reviewed-By: Robert Nagy Reviewed-By: Yagiz Nizipli Reviewed-By: Erick Wendel Reviewed-By: Matteo Collina Reviewed-By: Debadree Chatterjee --- lib/internal/streams/operators.js | 5 ++++- test/parallel/test-stream-drop-take.js | 24 +++++++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/lib/internal/streams/operators.js b/lib/internal/streams/operators.js index 9841723622418b..65c87d6e456bdf 100644 --- a/lib/internal/streams/operators.js +++ b/lib/internal/streams/operators.js @@ -409,7 +409,10 @@ function take(number, options = undefined) { } if (number-- > 0) { yield val; - } else { + } + + // Don't get another item from iterator in case we reached the end + if (number <= 0) { return; } } diff --git a/test/parallel/test-stream-drop-take.js b/test/parallel/test-stream-drop-take.js index cb55a4f7ee1813..97e6c74dfa67ea 100644 --- a/test/parallel/test-stream-drop-take.js +++ b/test/parallel/test-stream-drop-take.js @@ -4,7 +4,7 @@ const common = require('../common'); const { Readable, } = require('stream'); -const { deepStrictEqual, rejects, throws } = require('assert'); +const { deepStrictEqual, rejects, throws, strictEqual } = require('assert'); const { from } = Readable; @@ -49,6 +49,28 @@ const naturals = () => from(async function*() { })().then(common.mustCall()); } + +// Don't wait for next item in the original stream when already consumed the requested take amount +{ + let reached = false; + let resolve; + const promise = new Promise((res) => resolve = res); + + const stream = from((async function *() { + yield 1; + await promise; + reached = true; + yield 2; + })()); + + stream.take(1) + .toArray() + .then(common.mustCall(() => { + strictEqual(reached, false); + })) + .finally(() => resolve()); +} + { // Coercion (async () => {