diff --git a/spec.bs b/spec.bs index 4645121..3702af4 100644 --- a/spec.bs +++ b/spec.bs @@ -568,7 +568,94 @@ For now, see [https://github.com/wicg/observable#operators](https://github.com/w
The takeUntil(|notifier|) method steps are: - 1. TODO: Spec this and use |notifier|. + 1. Let |sourceObservable| be [=this=]. + + 1. Let |observable| be a [=new=] {{Observable}} whose [=Observable/subscribe callback=] is an + algorithm that takes a {{Subscriber}} |subscriber| and does the following: + + 1. Let |controller| be a [=new=] {{AbortController}}. + +
+ Note that this method involves Subscribing to two {{Observable}}s: (1) |notifier|, and (2) + |sourceObservable|. This |controller| is how we "unsubscribe" from **both** of them. We + do this in both of the following situations: + + 1. |notifier| starts emitting values (either "next" or "error"). In this case, we + unsubscribe from |notifier| since we got all we need from it, and no longer need it + to keep producing values. We also unsubscribe from |sourceObservable|, because it + no longer needs to produce values that get plumbed through this method's returned + |observable|, because we're manually ending the subscription to |observable|, since + |notifier| finally produced a value. + + 1. |sourceObservable| either {{Subscriber/error()}}s or {{Subscriber/complete()}}s + itself. In this case, we unsubscribe from |notifier| since we no longer need to + listen for values it emits in order to determine when |observable| can stop + mirroring values from |sourceObservable| (since |sourceObservable| ran to + completion by itself). Unsubscribing from |sourceObservable| isn't necessary, since + its subscription has exhausted itself. +
+ + 1. Let |signal| be the result of [=creating a dependent abort signal=] from the list + «|controller|'s [=AbortController/signal=], |subscriber|'s [=Subscriber/signal=]», using + {{AbortSignal}}, and the [=current realm=]. + + 1. Let |notifierObserver| be a new [=internal observer=], initialized as follows: + + : [=internal observer/next steps=] + :: 1. Run |subscriber|'s {{Subscriber/complete()}} method. + + 1. [=AbortController/Signal abort=] |controller|. + + : [=internal observer/error steps=] + :: 1. Run |subscriber|'s {{Subscriber/complete()}} method. + + 1. [=AbortController/Signal abort=] |controller|. + + Note: We do not specify [=internal observer/complete steps=], because if the |notifier| + {{Observable}} completes itself, we do not need to complete the |subscriber| associated + with the |observable| returned from this method. Rather, the |observable| will continue to + mirror |sourceObservable| uninterrupted. + + 1. Let |options| be a new {{SubscribeOptions}} whose {{SubscribeOptions/signal}} is |signal|. + + 1. Subscribe to |notifier| given + |notifierObserver| and |options|. + + 1. If |subscriber|'s [=Subscriber/active=] is false, then return. + + Note: This means that |sourceObservable|'s [=Observable/subscribe callback=] will not even + get invoked once, if |notifier| synchronously emits a value. If |notifier| only + "completes" synchronously though (without emitting a "next" or "error" value), then + |subscriber|'s [=Subscriber/active=] will still be true, and we proceed to subscribe to + |sourceObservable|, which |observable| will mirror uninterrupted. + + 1. Let |sourceObserver| be a new [=internal observer=], initialized as follows: + + : [=internal observer/next steps=] + :: Run |subscriber|'s {{Subscriber/next()}} method, given the passed in value. + + : [=internal observer/error steps=] + :: 1. Run |subscriber|'s {{Subscriber/error()}} method, given the passed in error. + + 1. [=AbortController/Signal abort=] |controller|. + + : [=internal observer/complete steps=] + :: 1. Run |subscriber|'s {{Subscriber/complete()}} method. + + 1. [=AbortController/Signal abort=] |controller|. + + Note: |sourceObserver| is mostly a pass-through, mirroring everything that + |sourceObservable| emits, with the exception of having the ability to unsubscribe from the + |notifier| {{Observable}} in the case where |sourceObservable| is exhausted before + |notifier| emits anything. + + 1. Subscribe to |sourceObservable| + given |sourceObserver| and |options|. + + 1. Return |observable|.