Consider the following:
// Defining a function
const addTwoNumbers = a => b => () => {
console.log(`Adding ${a} + ${b}`);
return a + b;
}
// Defining another function
const increment = addTwoNumbers(1);
// Defining another function
const incFive = increment(5);
// Invoking the final function to get a result
const result = incFive();
// Result is 6
console.log(`Result is ${result}`);
// Invoke 3 more times
[incFive, incFive, incFive].forEach(
fn => fn()
);
Notice how we're running the code 1 + 5
every time we invoke incFive
? If you run this code you'll see
Adding 1 + 5
Result is 6
Adding 1 + 5
Adding 1 + 5
Adding 1 + 5
The code in the function is "run" 4 time in total even though the function is defined only once.
That's sort of how observables work! subscribe
says to run the observable, so if you subscribe 10 times, you run the observable 10 times.
Of course, this changes a bit if you're dealing with a "hot" observable. Using concat
to repeat an observable that listens to button licks (for example) doesn't make much sense. Using concat
to request updates from a server, however, makes a lot more sense.
It's nice to define an observable once and be able to re-use it. Above, the line below "invoke 3 more times" could be rewritten as:
// Redefine 3 more times
[addTwoNumbers(1)(5),addTwoNumbers(1)(5), addTwoNumbers(1)(5)].forEach(
fn => fn()
);
But that's a hassle! Also, sometimes you want to define a function one place and invoke it in a separate place altogether. By then you may not know how to redefine it. The same is true with observables.