Aug 21, 2013 at 11:13 AM
Edited Aug 21, 2013 at 11:17 AM
You may be interested in
this related discussion
Question is: are these two forms completely equivalent?
Functionally, yes. Semantically, no.
If not, what are advantages/disadvantes of each relative to exception handling, performance, etc, etc.
Exception handling: no difference. Performance: not much, if any at all.
Ultimately, the difference is a matter of style.
Rx is a framework that allows us to query
data. The idea is to declare
we want, not how
to get it. A declarative syntax makes our code much more compact and closer to the specification, which makes it simpler to understand. Your
query reads like this:
- Defer the source to add a subscription side effect.
- Do a computation side effect for every element in the source.
- Finally, when the source terminates or is canceled, execute a side effect.
The query reads just like a specification.
is the most flexible generator that Rx has to offer. It gives us a context in which we can functionally or imperatively define any
observable behavior that we may need. Most operators in Rx could be implemented in terms of
alone. Your Create
query reads like this:
- Create a new observable.
- Start with a subscription side effect.
- Create a query: Do a computation side effect for every element in the source.
- Subscribe the observer to the previous query.
- Create a disposable side effect.
- return a composite disposable that disposes of the previous subscription and then executes the previous disposable side effect, after the source terminates or is canceled.
Use the right tool for the job. You probably want to be declarative when possible, so your
query is certainly better in this case.
In general, it's better to write composite queries with existing operators rather than using
. You should only fallback to Create
when you need custom behavior that isn't easily or elegantly defined by composing existing operators, which shouldn't be very often.
is also useful for when you need to create an observable from nothing; i.e., you have no observable
, as in your example, or anything that can be converted into one. However, Rx also fills the gap by providing specialized generators that are more semantic than
, allowing us to create observables from nothing in a declarative way:
isn't necessary in more advanced scenarios as well; e.g., defining operators in a general-purpose library, such as Rx itself.
isn't used internally by Rx – all closures are implemented manually for the sake of improving stack traces while debugging queries. Ironically, perhaps, the way that Rx implements its native operators seems to be quite the opposite of