Skip to content

Commit 978f5c1

Browse files
committed
stream: simplify readableStreamFromIterable
Signed-off-by: Antoine du Hamel <duhamelantoine1995@gmail.com> PR-URL: #62651 Reviewed-By: Aviv Keller <me@aviv.sh>
1 parent 9b95c41 commit 978f5c1

2 files changed

Lines changed: 23 additions & 92 deletions

File tree

lib/internal/webstreams/readablestream.js

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const {
2424
Symbol,
2525
SymbolAsyncIterator,
2626
SymbolDispose,
27+
SymbolIterator,
2728
SymbolToStringTag,
2829
TypedArrayPrototypeGetLength,
2930
Uint8Array,
@@ -32,6 +33,7 @@ const {
3233
const {
3334
AbortError,
3435
codes: {
36+
ERR_ARG_NOT_ITERABLE,
3537
ERR_ILLEGAL_CONSTRUCTOR,
3638
ERR_INVALID_ARG_TYPE,
3739
ERR_INVALID_ARG_VALUE,
@@ -111,8 +113,6 @@ const {
111113
nonOpCancel,
112114
nonOpPull,
113115
nonOpStart,
114-
getIterator,
115-
iteratorNext,
116116
kType,
117117
kState,
118118
} = require('internal/webstreams/util');
@@ -1360,41 +1360,36 @@ function createReadableStreamState() {
13601360

13611361
function readableStreamFromIterable(iterable) {
13621362
let stream;
1363-
const iteratorRecord = getIterator(iterable, 'async');
1364-
1363+
const iteratorGetter = iterable[SymbolAsyncIterator] ?? iterable[SymbolIterator];
1364+
if (iteratorGetter == null || typeof iteratorGetter !== 'function') {
1365+
throw new ERR_ARG_NOT_ITERABLE(iterable);
1366+
}
1367+
const iterator = FunctionPrototypeCall(iteratorGetter, iterable);
13651368
const startAlgorithm = nonOpStart;
13661369

13671370
async function pullAlgorithm() {
1368-
const nextResult = iteratorNext(iteratorRecord);
1369-
const nextPromise = PromiseResolve(nextResult);
1370-
return PromisePrototypeThen(nextPromise, (iterResult) => {
1371-
if (typeof iterResult !== 'object' || iterResult === null) {
1372-
throw new ERR_INVALID_STATE.TypeError(
1373-
'The promise returned by the iterator.next() method must fulfill with an object');
1374-
}
1375-
if (iterResult.done) {
1376-
readableStreamDefaultControllerClose(stream[kState].controller);
1377-
} else {
1378-
readableStreamDefaultControllerEnqueue(stream[kState].controller, iterResult.value);
1379-
}
1380-
});
1371+
const iterResult = await iterator.next();
1372+
if (typeof iterResult !== 'object' || iterResult === null) {
1373+
throw new ERR_INVALID_STATE.TypeError(
1374+
'The promise returned by the iterator.next() method must fulfill with an object');
1375+
}
1376+
if (iterResult.done) {
1377+
readableStreamDefaultControllerClose(stream[kState].controller);
1378+
} else {
1379+
readableStreamDefaultControllerEnqueue(stream[kState].controller, await iterResult.value);
1380+
}
13811381
}
13821382

13831383
async function cancelAlgorithm(reason) {
1384-
const iterator = iteratorRecord.iterator;
13851384
const returnMethod = iterator.return;
13861385
if (returnMethod === undefined) {
1387-
return PromiseResolve();
1386+
return;
1387+
}
1388+
const iterResult = await FunctionPrototypeCall(returnMethod, iterator, reason);
1389+
if (typeof iterResult !== 'object' || iterResult === null) {
1390+
throw new ERR_INVALID_STATE.TypeError(
1391+
'The promise returned by the iterator.return() method must fulfill with an object');
13881392
}
1389-
const returnResult = FunctionPrototypeCall(returnMethod, iterator, reason);
1390-
const returnPromise = PromiseResolve(returnResult);
1391-
return PromisePrototypeThen(returnPromise, (iterResult) => {
1392-
if (typeof iterResult !== 'object' || iterResult === null) {
1393-
throw new ERR_INVALID_STATE.TypeError(
1394-
'The promise returned by the iterator.return() method must fulfill with an object');
1395-
}
1396-
return undefined;
1397-
});
1398