RxJS is a JavaScript library that enables the creation of asynchronous and event-based programs. The main type is the Observable
and a suite of functions and operators are provided to make it easier to work with the data coming through. This series will detail those operators (and a few stand-alone functions) and provide examples of their use.
In this post, we’re going to cover the audit
operator.
What does it do?
The audit
operator can be used to limit the number of values that are handled by the pipeline. We pass audit
a function that returns a second observable, that observable then controls which values get handled. All values coming from the original observable will be ignored. When the second observable sends out a value, audit
will allow the last value from the original observable through the pipeline.
This can be hard to get your head around just by having it explained. Let's take a look at an example that will clear it up.
Example
import { Subject, audit, interval } from 'rxjs';
const auditTrigger$ = new Subject<void>();
interval(1000)
.pipe(audit(() => auditTrigger$))
.subscribe(x => {
console.log(x);
});
setInterval(() => {
auditTrigger$.next();
}, 5000);
Here we’re using the interval
function as our observable. This sends out incrementing numbers every second, but when we run it we will see:
3
8
13
18
This is the audit
operator in action. We have set up audit
to respond to events from auditTrigger$
, which sends out a message every 5 seconds. So, every 5 seconds audit
gets the message to output that last value handled. We can see the emitted values being sent if we update our pipeline to log the emitted value before it gets to the audit function.
import { Subject, audit, interval, tap } from 'rxjs';
const auditTrigger$ = new Subject<void>();
interval(1000)
.pipe(
tap(x => console.log(`Value emitted: ${x}`)),
audit(() => auditTrigger$)
)
.subscribe(x => {
console.log(`Value handled: ${x}`);
});
setInterval(() => {
auditTrigger$.next();
}, 5000);
We’ve added the tap
operator to our pipeline and configured it to log the value. Now if we run this we see:
Value emitted: 0
Value emitted: 1
Value emitted: 2
Value emitted: 3
**Value handled: 3**
Value emitted: 4
Value emitted: 5
Value emitted: 6
Value emitted: 7
Value emitted: 8
**Value handled: 8**
Value emitted: 9
This would come in useful if we’ve got an observable that sends out a lot of values, but we don’t need to handle all of them. We could set it up to only process the values when another, less chatty, observable gets an update.
The source code for this example is available on GitHub: