Skip to content

Commit 590fdc5

Browse files
authored
Make async iterator return() and next() more like async generators
Previously, we would only set the async iterator's "ongoing promise" to null when the async iterator next steps succeeded. This meant that calling return() after a failed next() would not call the async iterator return steps, thus potentially preventing the cleanup of any associated resources. This changes the spec to reset the ongoing promise after the async iterator next steps complete, regardless of whether they succeed or fail.
1 parent fe3b0cc commit 590fdc5

File tree

1 file changed

+38
-25
lines changed

1 file changed

+38
-25
lines changed

index.bs

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12543,23 +12543,29 @@ The \[[Prototype]] [=internal slot=] of an [=asynchronous iterator prototype obj
1254312543
1. Let |value| be |next|, [=converted to an ECMAScript value=].
1254412544
1. Return [=!=] [$CreateIterResultObject$](|value|, <emu-val>false</emu-val>).
1254512545
1. Let |onFulfilled| be [=!=] [$CreateBuiltinFunction$](|fulfillSteps|, « »).
12546-
1. Perform [=!=] [$PerformPromiseThen$](|nextPromise|, |onFulfilled|,
12547-
<emu-val>undefined</emu-val>, |nextPromiseCapability|).
12546+
1. Let |rejectSteps| be the following steps, given |reason|:
12547+
1. Set |object|'s [=default asynchronous iterator object/ongoing promise=] to
12548+
null.
12549+
1. Set |object|'s [=default asynchronous iterator object/is finished=] to true.
12550+
1. [=ECMAScript/Throw=] |reason|.
12551+
1. Let |onRejected| be [=!=] [$CreateBuiltinFunction$](|rejectSteps|, « »).
12552+
1. Perform [=!=] [$PerformPromiseThen$](|nextPromise|, |onFulfilled|, |onRejected|,
12553+
|nextPromiseCapability|).
1254812554
1. Return |nextPromiseCapability|.\[[Promise]].
1254912555

12550-
1. Let |promise| be |object|'s [=default asynchronous iterator object/ongoing promise=].
12556+
1. Let |ongoingPromise| be |object|'s [=default asynchronous iterator object/ongoing promise=].
1255112557

12552-
1. If |promise| is not null, then:
12558+
1. If |ongoingPromise| is not null, then:
1255312559
1. Let |afterOngoingPromiseCapability| be [=!=] [$NewPromiseCapability$]({{%Promise%}}).
12554-
1. Let |onFulfilled| be [=!=] [$CreateBuiltinFunction$](|nextSteps|, « »).
12555-
1. Perform [=!=] [$PerformPromiseThen$](|promise|, |onFulfilled|,
12556-
<emu-val>undefined</emu-val>, |afterOngoingPromiseCapability|).
12560+
1. Let |onSettled| be [=!=] [$CreateBuiltinFunction$](|nextSteps|, « »).
12561+
1. Perform [=!=] [$PerformPromiseThen$](|ongoingPromise|, |onSettled|, |onSettled|,
12562+
|afterOngoingPromiseCapability|).
1255712563
1. Set |object|'s [=default asynchronous iterator object/ongoing promise=] to
1255812564
|afterOngoingPromiseCapability|.\[[Promise]].
1255912565

1256012566
1. Otherwise:
12561-
1. Run |nextSteps| and set |object|'s
12562-
[=default asynchronous iterator object/ongoing promise=] to the result.
12567+
1. Set |object|'s [=default asynchronous iterator object/ongoing promise=] to the result of
12568+
running |nextSteps|.
1256312569

1256412570
1. Return |object|'s [=default asynchronous iterator object/ongoing promise=].
1256512571
</div>
@@ -12599,31 +12605,38 @@ The \[[Prototype]] [=internal slot=] of an [=asynchronous iterator prototype obj
1259912605
<emu-val>undefined</emu-val>, « |error| »).
1260012606
1. Return |returnPromiseCapability|.\[[Promise]].
1260112607

12602-
1. If |object|'s [=default asynchronous iterator object/ongoing promise=] is not null, then:
12603-
1. Let |error| be a new {{ECMAScript/TypeError}}.
12604-
1. Perform [=!=] [$Call$](|returnPromiseCapability|.\[[Reject]],
12605-
<emu-val>undefined</emu-val>, « |error| »).
12606-
1. Return |returnPromiseCapability|.\[[Promise]].
12608+
1. Let |returnSteps| be the following steps:
12609+
1. Let |returnPromiseCapability| be [=!=] [$NewPromiseCapability$]({{%Promise%}}).
12610+
1. If |object|'s [=default asynchronous iterator object/is finished=] is true, then:
12611+
1. Let |result| be [$CreateIterResultObject$](|value|, <emu-val>true</emu-val>).
12612+
1. Perform [=!=] [$Call$](|returnPromiseCapability|.\[[Resolve]],
12613+
<emu-val>undefined</emu-val>, « |result| »).
12614+
1. Return |returnPromiseCapability|.\[[Promise]].
12615+
1. Set |object|'s [=default asynchronous iterator object/is finished=] to true.
12616+
1. Return the result of running the [=asynchronous iterator return=] algorithm for
12617+
|interface|, given |object|'s [=default asynchronous iterator object/target=], |object|,
12618+
and |value|.
1260712619

12608-
1. If |object|'s [=default asynchronous iterator object/is finished=] is true, then:
12609-
1. Let |result| be [=!=] [$CreateIterResultObject$](|value|,
12610-
<emu-val>true</emu-val>).
12611-
1. Perform [=!=] [$Call$](|returnPromiseCapability|.\[[Resolve]],
12612-
<emu-val>undefined</emu-val>, « |result| »).
12613-
1. Return |returnPromiseCapability|.\[[Promise]].
12620+
1. Let |returnStepsPromise| be null.
1261412621

12615-
1. Set |object|'s [=default asynchronous iterator object/is finished=] to true.
12622+
1. Let |ongoingPromise| be |object|'s [=default asynchronous iterator object/ongoing promise=].
1261612623

12617-
1. Let |returnPromise| be the result of running the [=asynchronous iterator return=] algorithm
12618-
for |interface|, given |object|'s [=default asynchronous iterator object/target=],
12619-
|object|, and |value|.
12624+
1. If |ongoingPromise| is not null, then:
12625+
1. Let |afterOngoingPromiseCapability| be [=!=] [$NewPromiseCapability$]({{%Promise%}}).
12626+
1. Let |onSettled| be [=!=] [$CreateBuiltinFunction$](|returnSteps|, « »).
12627+
1. Perform [=!=] [$PerformPromiseThen$](|ongoingPromise|, |onSettled|, |onSettled|,
12628+
|afterOngoingPromiseCapability|).
12629+
1. Set |returnStepsPromise| to |afterOngoingPromiseCapability|.\[[Promise]].
12630+
12631+
1. Otherwise:
12632+
1. Set |returnStepsPromise| to the result of running |returnSteps|.
1262012633

1262112634
1. Let |fulfillSteps| be the following steps:
1262212635
1. Return [=!=] [$CreateIterResultObject$](|value|, <emu-val>true</emu-val>).
1262312636

1262412637
1. Let |onFulfilled| be [=!=] [$CreateBuiltinFunction$](|fulfillSteps|, « »).
1262512638

12626-
1. Perform [=!=] [$PerformPromiseThen$](|returnPromise|, |onFulfilled|,
12639+
1. Perform [=!=] [$PerformPromiseThen$](|returnStepsPromise|, |onFulfilled|,
1262712640
<emu-val>undefined</emu-val>, |returnPromiseCapability|).
1262812641

1262912642
1. Return |returnPromiseCapability|.\[[Promise]].

0 commit comments

Comments
 (0)