In the previous article, we learned how to create custom RxJS operators. In this one, I’d like to talk about one of the lesser known observables — defer — and explain how we can use it to solve the situations detailed below.

Imagine that we need to create a custom operator that takes a function, and executes it only upon the first source emission. Let’s implement such an operator, tapOnce :

The code is straightforward; We leverage the tap operator to run the passed function once, based on the status of the run flag variable. Now, let’s use our operator:

Everything works well. We see our emoji once, during the first source emission. Now, let’s add an additional subscriber:

If we look at the console, we only see a single emoji. The problem is that both subscribers share the same lexical scope, and therefore reference the same run variable. We need a way of deferring the creation of the observable until someone subscribes.

Defer to the rescue:

The defer observable takes a function that returns an ObservableInput . The code inside of defer is executed only upon subscription, and not during creation time. Using this approach and thanks to JS closures, each subscriber gets its own lexical scope.

Let’s create a simple implementation of defer to understand how it works:

defer returns a new observable, which upon subscription invokes the factory function, and uses it as the source.

Let’s see more use cases where we can leverage the defer observable. Let’s say we have an expression that we want to evaluate only when someone subscribes. For example:

In this example, each subscriber will get the same random value. We can solve this by using defer , so that the expression will be evaluated only when someone subscribed to the source, and not beforehand:

Another use case is when we want to defer a promise execution until someone subscribes:

Promises are naturally eager; They are executed regardless of the numbers of handlers. We can convert a Promise to become Observable-like (i.e., lazy) by using the defer observable.

🚀 In Case You Missed It

Here are a few of my open source projects: