Subscriber
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
Experimental: This is an experimental technology
Check the Browser compatibility table carefully before using this in production.
The Subscriber interface of the Observable API represents a subscription to a stream of observable values, and contains methods to manage the lifecycle of that subscription.
Instance properties
active-
A boolean value that indicates whether the subscription is active or not.
signal-
An internally created
AbortSignalthat is aborted when the subscription completes, errors, or all observers unsubscribe.
Instance methods
addTeardown()-
Registers a callback to clean up resources when the subscription completes, errors, or all observers unsubscribe.
complete()-
Closes the subscription and notifies observers that the stream has completed successfully.
error()-
Closes the subscription and notifies observers of an error.
next()-
Sends a value to the observers of the subscription.
Description
A Subscriber object is passed to the callback supplied to the Observable() constructor when the first observer subscribes. Additional observers share this Subscriber while it is active. After the subscription completes, errors, or all observers unsubscribe, the next subscription invokes the callback with a new Subscriber. You cannot construct a Subscriber directly.
Note:
This shared-subscription behavior may change. A proposal to give each observer its own Subscriber would make each subscription start a separate execution instead of reusing an active subscription.
The producer calls Subscriber.next(), Subscriber.error(), and Subscriber.complete() to send values and notifications to observers. The observers define how to handle these notifications through the corresponding callbacks passed to Observable.subscribe(). The producer can also register cleanup callbacks with Subscriber.addTeardown().
Examples
For additional examples, see Creating custom observables.
Basic Observable() example
In this example, we print the numbers 1 to 10 to the page. When the producer completes the subscription, the teardown callback clears the interval, and then the observer's complete callback displays a completion message.
HTML
The markup includes a single <p> element to display the count, and a <button> to start the count.
<button>Start count</button>
<p></p>
JavaScript
In the JavaScript, we first grab a reference to the <p> and <button> elements, then register an event listener on the <button> so that the count will start when it is clicked:
const outputElem = document.querySelector("p");
const btn = document.querySelector("button");
btn.addEventListener("click", () => {
btn.disabled = true;
const observable = new Observable((subscriber) => {
let i = 1;
const interval = setInterval(() => {
if (i === 11) {
subscriber.complete();
} else {
subscriber.next(i);
}
i++;
}, 500);
subscriber.addTeardown(() => {
if (btn.textContent === "Start count") {
btn.textContent = "Restart count";
}
clearInterval(interval);
btn.disabled = false;
});
});
observable.subscribe({
next(value) {
outputElem.textContent = value;
},
complete() {
outputElem.textContent = "Count complete";
},
});
});
Inside the click event handler function:
- We disable the button so that another click cannot start an overlapping count. We then use the
Observable()constructor to create a new observable. Inside its callback function, we declare a variableiwith a value of1. We then use aWindow.setInterval()call to check the value ofievery 500 milliseconds. If the value has reached11, we call thecomplete()method to complete the subscription. If not, we callnext()to send the current count to the observer. - At the end of the interval,
iis incremented by 1. - We also register a teardown callback using
addTeardown(). Inside it, we change the text on the<button>to "Restart count" if it doesn't already say that — this is more suitable if the count has already been run. And more importantly, we clear the interval (viaWindow.clearInterval()) when the subscription ends and re-enable the button for the next count. - Finally, we subscribe to the observable by calling
Observable.subscribe(). Inside thesubscribe()method's argument, we define the observer callbacks invoked by theSubscribermethods in the previous block — thenext()callback prints the value passed to it to the<p>element (i, in the code above that calls it), and thecomplete()callback prints "Count complete" to the<p>element.
Result
The example renders like so:
Press the button. Every 500 milliseconds, the current count is printed to the page. After displaying 10, the next interval callback completes the subscription and displays "Count complete".
The teardown callback changes the button text to "Restart count" and re-enables it before the observer's complete() callback runs.
Specifications
| Specification |
|---|
| Observable> # subscriber-api> |