mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-01 07:33:12 +08:00
Read the final result's value only for sync pipeline sources
for await reads the value of a done result only through the async-from-sync wrapper; an async iterator's done result is not read. The source's generator read it for both, so an async iterator whose done result has a throwing value getter rejected the pipeline. It now reads and awaits the final value only when the iterator is sync.
This commit is contained in:
@@ -4085,14 +4085,23 @@ function lowerDynIterableSource(
|
||||
type: BOOL,
|
||||
loc,
|
||||
},
|
||||
// the final value is awaited too: a rejection rejects the
|
||||
// pump, and the finished iterator is not closed
|
||||
// a sync iterator's final value is awaited too: a rejection
|
||||
// rejects the pump, and the finished iterator is not closed.
|
||||
// An async iterator's final value is not read.
|
||||
then: [
|
||||
{ kind: "assign", localId: valueId, value: get(step(), "value"), loc },
|
||||
{
|
||||
kind: "if",
|
||||
cond: awaitsValue(),
|
||||
then: [{ kind: "exprStmt", expr: awaitDyn(value()), loc }],
|
||||
cond: sync(),
|
||||
then: [
|
||||
{ kind: "assign", localId: valueId, value: get(step(), "value"), loc },
|
||||
{
|
||||
kind: "if",
|
||||
cond: awaitsValue(),
|
||||
then: [{ kind: "exprStmt", expr: awaitDyn(value()), loc }],
|
||||
else_: null,
|
||||
loc,
|
||||
},
|
||||
],
|
||||
else_: null,
|
||||
loc,
|
||||
},
|
||||
|
||||
@@ -135,3 +135,37 @@ for (const [label, source] of [["finalRejects", finalRejects], ["finalResolves",
|
||||
console.log(label, "rejected", err.message);
|
||||
}
|
||||
}
|
||||
|
||||
// the final result's value is read for a sync iterator only: an async
|
||||
// iterator's done result is not read, so a throwing value getter there is
|
||||
// never called
|
||||
function finalResult(label, i) {
|
||||
if (i === 1) return { value: `${label}1`, done: false };
|
||||
return {
|
||||
done: true,
|
||||
get value() {
|
||||
throw new Error(`${label} final value read`);
|
||||
},
|
||||
};
|
||||
}
|
||||
function asyncFinal() {
|
||||
let i = 0;
|
||||
return { [Symbol.asyncIterator]() { return { async next() { i++; return finalResult("async", i); } }; } };
|
||||
}
|
||||
function syncFinal() {
|
||||
let i = 0;
|
||||
return { [Symbol.iterator]() { return { next() { i++; return finalResult("sync", i); } }; } };
|
||||
}
|
||||
async function runFinal(label, source) {
|
||||
try {
|
||||
await pipelineP(
|
||||
pick(source),
|
||||
new Writable({ objectMode: true, write(c, _e, cb) { console.log(label, "write", c); cb(); } }),
|
||||
);
|
||||
console.log(label, "resolved");
|
||||
} catch (err) {
|
||||
console.log(label, "rejected", err.message);
|
||||
}
|
||||
}
|
||||
await runFinal("async final", asyncFinal());
|
||||
await runFinal("sync final", syncFinal());
|
||||
|
||||
Reference in New Issue
Block a user