What's the difference between the RxJS operators "buffer" and "bufferWhen"?

Viewed 678

I'm learning Angular and RxJS. Reading a book called RxJS in action I saw a mention of both operators. The first one receives and observable as an argument and the second one receives a selector function. It seems both buffer content based on these arguments.

What's the difference between them? When should I use a buffer instead of a bufferWhen operator?

1 Answers

buffer subscribes to its argument one time, with each emission from that subscription signalling the current buffer to close and emit, restarting the buffer.

The argument to bufferWhen is a function that returns an observable. bufferWhen calls it and subscribes to the result immediately, waiting for an emission to signal the close of its buffer. Crucially, the first emission will be the only one that matters, because upon that event, the buffer closes, the subscription to the signal observable ends, and the steps in this paragraph repeat until the observable we're buffering completes.

When is this useful? Sometimes when buffering an observable, you may need to do some setup before you can emit the signal at the right time. This setup could involve generating some initial value, perhaps based on the current "state of the world", or generated randomly. As of this writing, the Rx docs for bufferWhen describe an example of buffering on a timer that lasts a different random duration each time.

Addendum: to visualize the difference between the two, it's useful to see bufferWhen implemented using buffer:

const myBufferWhen = fn => buffer(
  defer(fn).pipe(
    take(1),
    repeat()
  )
);
Related