diff --git a/doc/observable.md b/doc/observable.md index 40bda2b7a1..8921e2d6fa 100644 --- a/doc/observable.md +++ b/doc/observable.md @@ -69,9 +69,9 @@ ES2015 introduced [generator functions and iterators](https://developer.mozilla. | | Producer | Consumer | | --- | --- | --- | | **Pull** | **Passive:** produces data when requested. | **Active:** decides when data is requested. | -| **Push** | **Active:** produces data at its own pace. | **Passive:** just reacts to data sent to it. | +| **Push** | **Active:** produces data at its own pace. | **Passive:** reacts to received data. | -**What is Push?** In Push systems, the Producer determines when to send data to the Consumer The Consumer itself is unaware of when the data will be received. +**What is Push?** In Push systems, the Producer determines when to send data to the Consumer. The Consumer is unaware of when it will receive that data. Promises are the most common type of Push system in JavaScript today. A Promise (the Producer) delivers a resolved value to registered callbacks (the Consumers), but unlike functions, it is the Promise which is in charge of determining precisely when that value is "pushed" to the callbacks. @@ -149,7 +149,7 @@ console.log(foo.call()); console.log('after'); ``` -You will obviously see the output: +You will see the output: ```none "before" @@ -259,19 +259,19 @@ Conclusion: ## Anatomy of an Observable -Observables are **created** using `Rx.Observable.create` or a creation operator, are **subscribed** to with an Observer, **execute** to deliver `next` / `error` / `complete` notifications to the Observer, and their execution may be **disposed**. These four aspects are all encoded in an Observable instance, but some of these aspects are related to other types, like Observer an Subscription. +Observables are **created** using `Rx.Observable.create` or a creation operator, are **subscribed** to with an Observer, **execute** to deliver `next` / `error` / `complete` notifications to the Observer, and their execution may be **disposed**. These four aspects are all encoded in an Observable instance, but some of these aspects are related to other types, like Observer and Subscription. -Four core Observable concerns: -- **Creation** -- **Subscribe** -- **Execution** -- **Disposal** +Core Observable concerns: +- **Creating** Observables +- **Subscribing** to Observables +- **Executing** the Observable +- **Disposing** Observables ### Creating Observables `Rx.Observable.create` is an alias for the `Observable` constructor, and it takes one argument: the `subscribe` function. -The following example creates an Observable to emit the string `'hi'` every one second to an Observer. +The following example creates an Observable to emit the string `'hi'` every second to an Observer. ```js var observable = Rx.Observable.create(function subscribe(observer) { @@ -310,9 +310,9 @@ The code inside `Observable.create(function subscribe(observer) {...})` represen There are three types of values an Observable Execution can deliver: -- "Next" notification: an actual value such as a Number, a String, an Object, etc. -- "Error" notification: a JavaScript Error or exception. -- "Complete" notification: a valueless event. +- "Next" notification: sends a value such as a Number, a String, an Object, etc. +- "Error" notification: sends a JavaScript Error or exception. +- "Complete" notification: does not send a value. Next notifications are the most important and most common type: they represent actual data being delivered to an Observer. Error and Complete notifications may happen only once during the Observable Execution, and there can only be either one of them. @@ -373,7 +373,7 @@ When `observable.subscribe` is called, the Observer gets attached to the newly c var subscription = observable.subscribe(x => console.log(x)); ``` -The Subscription represents the ongoing execution, and has a minimal API, which primarily simply allows you to cancel that execution. Read more about the [`Subscription` type here](./overview.html#subscription). With `subscription.unsubscribe()` you can cancel the ongoing execution: +The Subscription represents the ongoing execution, and has a minimal API which allows you to cancel that execution. Read more about the [`Subscription` type here](./overview.html#subscription). With `subscription.unsubscribe()` you can cancel the ongoing execution: ```js var observable = Rx.Observable.from([10, 20, 30]); @@ -394,7 +394,7 @@ var observable = Rx.Observable.create(function subscribe(observer) { var intervalID = setInterval(() => { observer.next('hi'); }, 1000); - + // Provide a way of canceling and disposing the interval resource return function unsubscribe() { clearInterval(intervalID); @@ -402,14 +402,14 @@ var observable = Rx.Observable.create(function subscribe(observer) { }); ``` -Just like `observable.subscribe` resembles `Observable.create(function subscribe() {...})`, the `unsubscribe` we return from `subscribe` is conceptually equal to `subscription.unsubscribe`. In fact, if we remove the ReactiveX types surrounding these concepts, we get some JavaScript that is clearly simple: +Just like `observable.subscribe` resembles `Observable.create(function subscribe() {...})`, the `unsubscribe` we return from `subscribe` is conceptually equal to `subscription.unsubscribe`. In fact, if we remove the ReactiveX types surrounding these concepts, we're left with rather straightforward JavaScript. ```js function subscribe(observer) { var intervalID = setInterval(() => { observer.next('hi'); }, 1000); - + return function unsubscribe() { clearInterval(intervalID); }; diff --git a/doc/operators.md b/doc/operators.md index a63c08ee97..b5d18bdbef 100644 --- a/doc/operators.md +++ b/doc/operators.md @@ -8,7 +8,7 @@ Operators are **methods** on the Observable type, such as `.map(...)`, `.filter( An Operator is a function take creates a new Observable based on the current Observable. This is a pure operation: the previous Observable stays unmodified. -An Operator is essentially a pure function which takes one Observable as input and generates another Observable as output. A subscribe on the output Observable will cause also a subscribe on the input Observable. In the following example, we create a custom operator/function that simply multiplies by 10 each value delivered by the input Observable: +An Operator is essentially a pure function which takes one Observable as input and generates another Observable as output. Subscribing to the output Observable will also subscribe to the input Observable. In the following example, we create a custom operator function that multiplies each value received from the input Observable by 10: ```js function multiplyByTen(input) { diff --git a/doc/subject.md b/doc/subject.md index 9797c15a5e..9d4400180f 100644 --- a/doc/subject.md +++ b/doc/subject.md @@ -69,7 +69,7 @@ There are also a few specializations of the `Subject` type: `BehaviorSubject`, ` ## Multicasted Observables -Whenever we refer to "a multicasted Observable", that means an Observable execution that passes through a Subject. Otherwise, a "plain (unicast) Observable" behaves like an *invokable collection of future values*, with no sharing assumed. +A "multicasted Observable" passes notifications through a Subject which may have many subscribers, whereas a plain "unicast Observable" only sends notifications to a single Observer. A multicasted Observable uses a Subject under the hood to make multiple Observers see the same Observable execution. @@ -94,11 +94,11 @@ multicasted.connect(); `multicast` returns an Observable that looks like a normal Observable, but works like a Subject when it comes to subscribing. `multicast` returns a `ConnectableObservable`, which is simply an Observable with the `connect()` method. -The `connect()` method is important to determine exactly when will the shared Observable execution start. Because `connect()` does `source.subscribe(subject)` under the hood, `connect()` returns a Subscription, which you can unsubscribe in order to cancel the shared Observable execution. +The `connect()` method is important to determine exactly when the shared Observable execution will start. Because `connect()` does `source.subscribe(subject)` under the hood, `connect()` returns a Subscription, which you can unsubscribe from in order to cancel the shared Observable execution. ### Reference counting -Calling `connect()` manually and handling the Subscription is often cumbersome. Usually, we want to *automatically* connect when the first Observer arrives, and automatically cancel the shared execution when the last Observer unsubscribes. +Calling `connect()` manually and handling the Subscription is often cumbersome. Usually, we want to *automatically* connect when the first Observer arrives, and automatically cancel the shared execution when the last Observer unsubscribes. Consider the following example where subscriptions occur as outlined by this list: @@ -124,7 +124,7 @@ var subscription1, subscription2, subscriptionConnect; subscription1 = multicasted.subscribe({ next: (v) => console.log('observerA: ' + v) }); -// We should call `connect()` here, because the first +// We should call `connect()` here, because the first // subscriber to `multicasted` is interested in consuming values subscriptionConnect = multicasted.connect(); @@ -146,7 +146,7 @@ setTimeout(() => { }, 2000); ``` -If we wish to avoid explicit calls to `connect()`, we use the method `refCount()` on the ConnectableObservable. It does reference counting: keeps track of how many subscribers are registered on the ConnectableObservable. `refCount()` calls `connect()` when that number goes from `0` to `1`, and keeps the subscription for the shared execution. When the number of subscribers goes from `1` to `0`, it finally unsubscribes the subscription to the shared execution. +If we wish to avoid explicit calls to `connect()`, we can use ConnectableObservable's `refCount()` method (reference counting), which returns an Observable that keeps track of how many subscribers it has. When the number of subscribers increases from `0` to `1`, it will call `connect()` for us, which starts the shared execution. Only when the number of subscribers decreases from `1` to `0` will it be fully unsubscribed, stopping further execution. `refCount` makes the multicasted Observable automatically start executing when the first subscriber arrives, and stop executing when the last subscriber leaves. @@ -187,7 +187,7 @@ setTimeout(() => { Which executes with the output: -```none +```none observerA subscribed observerA: 0 observerB subscribed @@ -198,7 +198,7 @@ observerB: 2 observerB unsubscribed ``` -The `refCount()` method only exists on ConnectableObservables, and it returns an `Observable`, not another ConnectableObservable. +The `refCount()` method only exists on ConnectableObservable, and it returns an `Observable`, not another ConnectableObservable. ## BehaviorSubject @@ -206,10 +206,10 @@ One of the variants of Subjects is the `BehaviorSubject`, which has a notion of BehaviorSubjects are useful for representing "values over time". For instance, an event stream of birthdays is a Subject, but the stream of a person's age would be a BehaviorSubject. -Notice in the following example how the BehaviorSubject is initialized with the value `0` which the first Observer receives when it subscribes. Also, the second Observer subscribes after the value `2` was sent, but will still receive that value: +In the following example, the BehaviorSubject is initialized with the value `0` which the first Observer receives when it subscribes. The second Observer receives the value `2` even though it subscribed after the value `2` was sent. ```js -var subject = new Rx.BehaviorSubject(0 /* the initial value */); +var subject = new Rx.BehaviorSubject(0); // 0 is the initial value subject.subscribe({ next: (v) => console.log('observerA: ' + v) @@ -238,14 +238,14 @@ observerB: 3 ## ReplaySubject -The `ReplaySubject` subclass of `Subject` is like `BehaviorSubject` in that it can send old values to new incoming subscribers, but it in general is able to *record* a part of the Observable execution. +A `ReplaySubject` is similar to a `BehaviorSubject` in that it can send old values to new subscribers, but it can also *record* a part of the Observable execution. A `ReplaySubject` records multiple values from the Observable execution and replays them to new subscribers. -You may, for instance, specify how many values to replay, e.g.: +When creating a `ReplaySubject`, you can specify how many values to replay: ```js -var subject = new Rx.ReplaySubject(3 /* bufferSize */); +var subject = new Rx.ReplaySubject(3); // buffer 3 values for new subscribers subject.subscribe({ next: (v) => console.log('observerA: ' + v)