3. The lifecycle: next, error, complete
The signals an Observable can send
Every Observable "talks" to its subscriber through three kinds of notification. They're worth memorizing, because together they describe the whole lifecycle of a stream — from the first value to the very end.
next(value)— "here's the next value." It can fire many times: 0, 1, 5, millions.error(err)— "something went wrong, I won't send anything more." This is a terminal signal: after it, the stream is dead.complete()— "that's it, I'm finished, no more values." Also terminal, but without an error.
The stream contract
Formally it's written as next* (error | complete)?. Read it as: "any number of nexts in a row, then maybe either an error or a complete (not both, and never more than once)."
In other words, error and completion are mutually exclusive. Once one happens, the stream is closed for good — calling next afterward is pointless.
The object form of subscribe
In earlier lessons we passed subscribe a plain function — that's the callback for next. But when you also want to handle the error and the completion, pass an object with three keys: { next, error, complete }. Each one is optional.
Your task
- Inside the recipe function, loop over the
dataarray. Afor (const item of data) { ... }works well. - For each element, check: if it equals the string
'error', callsubscriber.error('Error!')and immediatelyreturn(to leave the function — there's nothing to do after an error). - If it's a normal element, send it with
subscriber.next(item). - After the loop (if no error occurred), call
subscriber.complete().
Expected log order: Next: Apple → Next: Banana → Error: Error!. After the error, Cherry and Complete never show up — the stream is dead.
const { Observable } = Rx;
const data = ['Apple', 'Banana', 'error', 'Cherry'];
const stream$ = new Observable(subscriber => {
for (const item of data) {
if (item === 'error') {
subscriber.error('Error!');
return;
}
subscriber.next(item);
}
subscriber.complete();
});
stream$.subscribe({
next: value => console.log('Next: ' + value),
error: error => console.log('Error: ' + error),
complete: () => console.log('Complete')
});