I can't find any relevant posts about this and I can't figure out the nuance from the documentation, what is the difference between auditTime and sampleTime operators?
auditTime(ms)
will keep storing the latest value for ms
milliseconds. After ms
have passed, if any value exists, it will pass along as a next notification
.
auditTime(ms) === audit(() => timer(ms, scheduler?))
.
u - units of time
1--3--5----------6-7-- values$
----|-----|----!-----| auditTime(5u)
----3-----5----------7 result
^ ^ ^
! - since the timer did not started, because there was no value after `5`, there won't be any value emitted further in the stream
^ - when the timer starts
It's also worth noticing that this timer starts only when at least one value has arrived.
Maybe visualizing the source code would help:
_next(value: T): void {
this.value = value; // Keep track of the oldest value
this.hasValue = true;
if (!this.throttled) { // If the timer didn't started yet, start it
let duration;
try {
const { durationSelector } = this;
duration = durationSelector(value); // Create observable; if `auditTime(d)`, it will be `() => timer(ms)`
} catch (err) {
return this.destination.error(err);
}
const innerSubscription = subscribeToResult(this, duration); // Subscribe to the inner observable
/* ... */
this.throttled = innerSubscription // Store the subscription
}
}
When the timer expires(i.e when the inner observable has emitted/completed), the value will be passed along:
// Called when the inner obs completes/emits a value
clearThrottle() {
const { value, hasValue, throttled } = this;
if (throttled) { // Did we have a timer(a subscription)? If yes, unsubscribe
this.remove(throttled);
this.throttled = null;
throttled.unsubscribe();
}
if (hasValue) { // If we have a value, send it do its destination
this.value = null;
this.hasValue = false;
this.destination.next(value);
}
}
sampleTime(ms)
, like auditTime(ms)
will keep track of the latest arrived value and will emit it further in the chain, with the exception that in sampleTime
the timer
(which decides when to emit
the value) is always active. This means that no matter if any value as arrived since the last emission, the timer will run. Now, if no new value arrived, it will simply not pass along the value.
Let's explore its source code:
_next(value: T) { // Keep track of the oldest value
this.lastValue = value;
this.hasValue = true;
}
notifyNext() { // When time is up, check if any `new` value came in since the last 'sample'
if (this.hasValue) { // If we have a value, then send it further
this.hasValue = false;
this.destination.next(this.lastValue);
}
}
Note that the value can be the same as the one which was previously emitted, but it must arrive while the current timer is active.
sampleTime
by default uses AsyncAction
s, which are managed by the AsyncScheduler
. Put differently, the timer
, in this case, is achieved with setInterval
.
sample(notifier)
follows the same logic, except that there is no scheduler, and the timer
is defined by the notifier
, which is an Observable
.
Compared to auditTime
:
u - units of time
1--3--5-------6-7-- values$
----|---|---|---|-- auditTime(5u)
----3---5-------7-- result
^ ^ ^ ^ ^
^ - when the timer starts
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With