Skip to content

Commit

Permalink
Spec the reduce() operator (#171)
Browse files Browse the repository at this point in the history
  • Loading branch information
domfarolino authored Sep 3, 2024
1 parent 35be035 commit d7bc48b
Showing 1 changed file with 62 additions and 2 deletions.
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 @@ -1679,7 +1679,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

0 comments on commit d7bc48b

Please sign in to comment.