fix(docs-infra): convert hard-coded `comparing-observables` examples into a proper mini-app (#34327)

Previously, the examples in the `comparing-observables` guide were hard-coded.
This made it impossible to test them and verify they are correct.

This commit fixes this by converting them into a proper mini-app. In a
subsequent commit, tests will be added to verify that the source code
works as expected (and guard against regressions).

Fixes #31024

PR Close #34327
This commit is contained in:
Sonu Kapoor 2019-12-10 09:34:32 -05:00 committed by Matias Niemelä
parent 7342d4b6f0
commit def4127bf1
4 changed files with 117 additions and 49 deletions

1
.github/CODEOWNERS vendored
View File

@ -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

View File

@ -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
});
subscription.unsubscribe();
// #enddocregion unsubscribe
// #docregion error
observable.subscribe(() => {
throw Error('my error');
});
// #enddocregion error
// #docregion chain
observable.pipe(map(v => 2 * v));
// #enddocregion chain

View File

@ -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

View File

@ -21,48 +21,47 @@ 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>
* Promises are not cancellable.
@ -70,19 +69,19 @@ sub.unsubscribe();
* 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
@ -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) => {
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>
@ -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>
@ -165,7 +168,6 @@ subscription.unsubscribe();</pre>
<pre>function handler(e) {
console.log(Clicked, e);
}
// Setup & begin listening
button.addEventListener(click, handler);
// Stop listening