Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,7 @@ testing/** @angular/fw-test
/aio/content/guide/observables.md @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/observables/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/comparing-observables.md @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/comparing-observables/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/observables-in-angular.md @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/examples/observables-in-angular/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/guide/practical-observable-usage.md @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
Expand Down
40 changes: 40 additions & 0 deletions aio/content/examples/comparing-observables/src/observables.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { map } from 'rxjs/operators';
import { Observable } from 'rxjs';

// #docregion observable

// declare a publishing operation
const observable = new Observable<number>(observer => {
// Subscriber fn...
});

// initiate execution
observable.subscribe(() => {
// observer handles notifications
});

// #enddocregion observable

// #docregion unsubscribe

const subscription = observable.subscribe(() => {
// observer handles notifications
});
Comment thread
gkalpak marked this conversation as resolved.
Resolved

subscription.unsubscribe();

// #enddocregion unsubscribe

// #docregion error

observable.subscribe(() => {
throw Error('my error');
});

// #enddocregion error

// #docregion chain

observable.pipe(map(v => 2 * v));

// #enddocregion chain
25 changes: 25 additions & 0 deletions aio/content/examples/comparing-observables/src/promises.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// #docregion promise
// initiate execution
const promise = new Promise<number>((resolve, reject) => {
// Executer fn...
});

promise.then(value => {
// handle result here
});

// #enddocregion promise

// #docregion chain

promise.then(v => 2 * v);

// #enddocregion chain

// #docregion error

promise.then(() => {
throw Error('my error');
});

// #enddocregion error
100 changes: 51 additions & 49 deletions aio/content/guide/comparing-observables.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,68 +21,67 @@ Observables are often compared to promises. Here are some key differences:

* Observables are not executed until a consumer subscribes. The `subscribe()` executes the defined behavior once, and it can be called again. Each subscription has its own computation. Resubscription causes recomputation of values.

<code-example hideCopy>
// declare a publishing operation
new Observable((observer) => { subscriber_fn });
// initiate execution
observable.subscribe(() => {
// observer handles notifications
});
</code-example>
<code-example
path="comparing-observables/src/observables.ts"
header="src/observables.ts (observable)"
region="observable">
</code-example>

* Promises execute immediately, and just once. The computation of the result is initiated when the promise is created. There is no way to restart work. All `then` clauses (subscriptions) share the same computation.

<code-example hideCopy>
// initiate execution
new Promise((resolve, reject) => { executer_fn });
// handle return value
promise.then((value) => {
// handle result here
});
</code-example>
<code-example
path="comparing-observables/src/promises.ts"
header="src/promises.ts (promise)"
region="promise">
</code-example>

### Chaining

* Observables differentiate between transformation function such as a map and subscription. Only subscription activates the subscriber function to start computing the values.


<code-example hideCopy>observable.pipe(map((v) => 2*v));</code-example>

<code-example
path="comparing-observables/src/observables.ts"
header="src/observables.ts (chain)"
region="chain">
</code-example>

* Promises do not differentiate between the last `.then` clauses (equivalent to subscription) and intermediate `.then` clauses (equivalent to map).


<code-example hideCopy>promise.then((v) => 2*v);</code-example>

<code-example
path="comparing-observables/src/promises.ts"
header="src/promises.ts (chain)"
region="chain">
</code-example>

### Cancellation

* Observable subscriptions are cancellable. Unsubscribing removes the listener from receiving further values, and notifies the subscriber function to cancel work.

<code-example hideCopy>
const sub = obs.subscribe(...);
sub.unsubscribe();
</code-example>
<code-example
path="comparing-observables/src/observables.ts"
header="src/observables.ts (unsubcribe)"
region="unsubscribe">
</code-example>

Comment thread
gkalpak marked this conversation as resolved.
Resolved
* Promises are not cancellable.

### Error handling

* Observable execution errors are delivered to the subscriber's error handler, and the subscriber automatically unsubscribes from the observable.

<code-example hideCopy>
obs.subscribe(() => {
throw Error('my error');
});
</code-example>
<code-example
path="comparing-observables/src/observables.ts"
header="src/observables.ts (error)"
region="error">
</code-example>

* Promises push errors to the child promises.

<code-example hideCopy>
promise.then(() => {
throw Error('my error');
});
</code-example>
<code-example
path="comparing-observables/src/promises.ts"
header="src/promises.ts (error)"
region="error">
</code-example>

### Cheat sheet

Expand All @@ -100,14 +99,16 @@ The following code snippets illustrate how the same kind of operation is defined
<tr>
<td>Creation</td>
<td>
<pre>new Observable((observer) => {
Comment thread
gkalpak marked this conversation as resolved.
Resolved
observer.next(123);
});</pre>
<pre>
new Observable((observer) => {
observer.next(123);
});</pre>
</td>
<td>
<pre>new Promise((resolve, reject) => {
resolve(123);
});</pre>
<pre>
new Promise((resolve, reject) => {
resolve(123);
});</pre>
</td>
</tr>
<tr>
Expand All @@ -118,14 +119,16 @@ The following code snippets illustrate how the same kind of operation is defined
<tr>
<td>Subscribe</td>
<td>
<pre>sub = obs.subscribe((value) => {
console.log(value)
});</pre>
<pre>
sub = obs.subscribe((value) => {
console.log(value)
});</pre>
</td>
<td>
<pre>promise.then((value) => {
console.log(value);
});</pre>
<pre>
promise.then((value) => {
console.log(value);
});</pre>
</td>
</tr>
<tr>
Expand Down Expand Up @@ -165,7 +168,6 @@ subscription.unsubscribe();</pre>
<pre>function handler(e) {
console.log(‘Clicked’, e);
}

Comment thread
gkalpak marked this conversation as resolved.
Resolved
Comment thread
gkalpak marked this conversation as resolved.
Resolved
// Setup & begin listening
button.addEventListener(‘click’, handler);
// Stop listening
Expand Down