Comments (10)
Thanks for raising this issue. Please check out Observable.from
in the "callback-style" branch. It does something very similar to what you're asking for. In fact, I think between Observable.of
and Observable.from
it should cover the bases.
The big design change I made is that I introduced Symbol.observable
. This works just like Symbol.iterator
: for some arbitrary "observable" type, it returns an observable object. Like iterators, observables have a Symbol.observable
method which just returns this
.
We could add Symbol.observable
to Promise.prototype as well, which would make them convertible with Observable.from
.
from proposal-observable.
It looks like the scenarios can be mapped to from
/of
like this:
- "observablesque" => Observable.from.
- valueType => Observable.of
- iterable => Observable.from
- object => Observable.of
- promise => Observable.from (potentially)
The only issue is that you have to know whether to call from
or of
in advance. That makes sense to me though, because the two operations are very different from a type point of view:
Observable.from(Observable<T>) : Observable<T>
Observable.from(Iterable<T>) : Observable<T>
Observable.of(T) : Observable<T>
Observable.of(T, U) : Observable<any>
Observable.of(T, U, V) : Observable<any>
...
I think a more heuristic casting function would be useful, but maybe not appropriate for the core API?
I can see Arrays and generators mapping to Observables just fine, but Strings are iterable, and I think most of the time people will want those to be mapped into an observable of item.
Again, I don't think I'd feel comfortable adding such a heuristic. The from
/of
distinction seems good to me and allows users to express their intent explicitly.
For promises and single values, do we just make an observable that nexts out one value? Should it complete/return with that one value also?
That's a good question. Observable.of
takes a variable number of arguments, so it makes sense to next
each one and then complete with void
(like all other iterable sequences).
For promises, my personal opinion is that it should next
the fulfillment value and then complete with void
. It's just so much easier to consume that way with the callback style:
Observable.from(promise).subscribe(
val => console.log(`Resolved with ${ val }`),
err => console.log(`Boo, rejection! ${ err }`));
And it has a nice symmetry with then
:
promise.then(
val => console.log(`Resolved with ${ val }`),
err => console.log(`Boo, rejection! ${ err }`));
from proposal-observable.
I think there should just be one method that you can use to convert anything to an observable, personally. Perhaps that's from
. of
seems more specialized.
On Promise conversion
Are we still going with the return
or completed
path returning a value? If so, it seems like Promises would map 1:1 with something like just returning the resolved value. However, that makes composing over the Observable painful. There are really three options:
new Observable(o => {
promise.then(x => {
o.next(x);
o.return();
}, err => o.error(err));
});
new Observable(o => {
promise.then(x => {
o.return(x);
}, err => o.error(err));
});
new Observable(o => {
promise.then(x => {
o.next(x);
o.return(x);
}, err => o.error(err));
});
I think 1 or 2 are acceptable. 3 seems weird. 1 makes it the easiest to compose. 2 gives more purpose to the whole "return having a value" thing, and means every Observable that has a return value could be treated somewhat like a promise.
My gut tells me the right thing to do is go with 1, and then have a specialized "ScalarObservable" that matches the signature of Observable, but only ever emits one value. That, of course doesn't need to be part of this proposal, but as a library implementor, I might just add a boolean check for an isScalar
or the like so I can optimize code paths.
from proposal-observable.
I think there should just be one method that you can use to convert anything to an observable, personally.
I'm a little worried that if you make such an all-accepting function, it will be a breaking change to make some type T observable-ish if it was previously not observable-ish. It would cause the behavior to go from:
from(T) : Observable<T>
to:
from(observablesque<T>) : Observable<T>
My gut tells me the right thing to do is go with 1
Mine too, but maybe @jhusain has a different opinion?
from proposal-observable.
Definitely in favor of 1 here. If observables don't have a return value it's as simple as the fact:
a; // value
[a]; // array containing one value.
That said, I think it's important to keep consistency with async iterators. So observables should probably behave consistently to those.
from proposal-observable.
The breaking change hazard is real unfortunately. Under the circumstances, we should probably go with option one.
from proposal-observable.
@domenic can you clarify what async iterators do here so observables can align?
Based on Babel indeed 1 is the correct thing to do: http://babeljs.io/repl/#?experimental=true&evaluate=true&loose=false&spec=false&playground=false&code=async%20function*%20foo()%7B%0A%20%20yield%201%3B%0A%7D%0A%0Avar%20f%20%3D%20foo()%3B%0Af.next().then(function()%7B%0A%20%20console.log(arguments)%3B%0A%7D)%3B%0Af.next().then(function()%7B%0A%20%20console.log(arguments)%3B%0A%7D)
from proposal-observable.
What am I clarifying? @zenparsing is the expert on async iterators anyway as it's his proposal. Your code looks a bit suspicious in that it does yield 1
instead of return 1
but I don't have any context.
from proposal-observable.
@domenic ok then, apologies for the ping don't waste time on it - @zenparsing will clarify it :)
from proposal-observable.
I think Observable.from solves this adequately for now. Closing.
from proposal-observable.
Related Issues (20)
- Invalid test based on Interface. HOT 1
- `obs.subscribe(next, error, complete)` should bind their callbacks to `undefined` when present HOT 5
- Why does `Observable.prototype.subscribe` report thrown errors from `observer.start(sub)` asynchronously instead of just propagating them?
- Minor spec bug WRT cleanup in `subscribe`
- `Observable.from` iteration functions incorrectly assume their observer parameter is native HOT 1
- [ALTERNATIVE] Proposal for an alternative
- Cleanup function should be passed to the SubscriptionObserver
- Simplification of Observable API HOT 69
- End a subscription if a completion token is returned HOT 1
- Even simpler API HOT 4
- Reduced API with async/await support HOT 23
- Observable should be async HOT 5
- Syntax Support HOT 4
- Alternative: Pub/Sub
- Moving to an API with AbortSignal HOT 9
- Retain core API and leave operators to user-land libraries HOT 15
- Permit unsubscribe to return a promise HOT 3
- Is there any update? HOT 34
- Support [Symbol.dispose]() for unsubscribe() HOT 1
- Unsubscribe
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from proposal-observable.