Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spec the reduce() operator #171

Merged
merged 3 commits into from
Sep 3, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 62 additions & 2 deletions spec.bs
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ dictionary SubscribeOptions {
};

callback Predicate = boolean (any value, unsigned long long index);
callback Reducer = any (any accumulator, any currentValue);
callback Reducer = any (any accumulator, any currentValue, unsigned long long index);
callback Mapper = any (any value, unsigned long long index);
// Differs from Mapper only in return type, since this callback is exclusively
// used to visit each element in a sequence, not transform it.
Expand Down Expand Up @@ -1604,7 +1604,67 @@ For now, see [https://github.com/wicg/observable#operators](https://github.com/w
The <dfn for=Observable method><code>reduce(|reducer|, |initialValue|, |options|)</code></dfn>
method steps are:

1. <span class=XXX>TODO: Spec this and use |reducer|, |initialValue|, and |options|.</span>
1. Let |p| [=a new promise=].

1. Let |controller| be a [=new=] {{AbortController}}.

1. Let |internal options| be a new {{SubscribeOptions}} whose {{SubscribeOptions/signal}} is the
result of [=creating a dependent abort signal=] from the list
«|controller|'s [=AbortController/signal=], |options|'s
{{SubscribeOptions/signal}} if non-null», using {{AbortSignal}}, and the [=current realm=].

1. If |internal options|'s {{SubscribeOptions/signal}} is [=AbortSignal/aborted=], then:

1. [=Reject=] |p| with |internal options|'s {{SubscribeOptions/signal}}'s
[=AbortSignal/abort reason=].

1. Return |p|.

1. [=AbortSignal/add|Add the following abort algorithm=] to |internal options|'s
{{SubscribeOptions/signal}}:

1. [=Reject=] |p| with |internal options|'s {{SubscribeOptions/signal}}'s [=AbortSignal/abort
reason=].

1. Let |idx| be an {{unsigned long long}}, initially 0.

1. Let |accumulator| be |initialValue| if it is given, and uninitialized otherwise.

1. Let |observer| be a new [=internal observer=], initialized as follows:

: [=internal observer/next steps=]
::
1. If |accumulator| is uninitialized (meaning no |initialValue| was passed in), then set
|accumulator| to the passed in |value|, set |idx| to |idx| + 1, and abort these steps.

Note: This means that |reducer| will not be called with the first |value| that [=this=]
produces set as the {{Reducer/currentValue}}. Rather, when the *second* value is
eventually emitted, we will call |reducer| with *it* as the {{Reducer/currentValue}},
and the first value (that we're saving here) as the {{Reducer/accumulator}}.

1. [=Invoke=] |reducer| with |accumulator| as {{Reducer/accumulator}}, the passed in
|value| as {{Reducer/currentValue}}, and |idx| as {{Reducer/index}}. Let |result| be
the returned value.

If <a spec=webidl lt="an exception was thrown">an exception |E| was thrown</a>, then
[=reject=] |p| with |E|, and [=AbortController/signal abort=] |controller| with |E|.

1. Set |idx| to |idx| + 1.

1. Set |accumulator| to |result|.

: [=internal observer/error steps=]
:: [=Reject=] |p| with the passed in <var ignore>error</var>.

: [=internal observer/complete steps=]
:: 1. If |accumulator| is not "<code>unset</code>", then [=resolve=] |p| with |accumulator|.

Otherwise, [=reject=] |p| with a {{TypeError}}.

1. <a for=Observable lt="subscribe to an Observable">Subscribe</a> to [=this=] given |observer|
and |internal options|.

1. Return |p|.
</div>


Expand Down
Loading