Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Single, Maybe and Completable #2469

Closed
passsy opened this issue Mar 16, 2017 · 14 comments
Closed

Add Single, Maybe and Completable #2469

passsy opened this issue Mar 16, 2017 · 14 comments

Comments

@passsy
Copy link

passsy commented Mar 16, 2017

RxJava 2 has the concept of Single, Maybe and Completable. They got quickly adopted by RxSwift 3.3.0.

I couldn't find anything about those reactive types in rxjs. Are they planned?

@kwonoj
Copy link
Member

kwonoj commented Mar 16, 2017

No, it's not planned. It is not a goal of v5 to create full-compliant operator set to other languge bindings or even v4, and there are some added opeator or dropped operator between. Once there is suffecient usecase and demand it can be obviously discussed in further.

@aluanhaddad
Copy link
Contributor

I'm also not sure I would look to RxJava for inspiration. Java is severely lacking in expressive power, even with its recent editions. JavaScript has long had better expressiveness as have most other languages.

@kwonoj
Copy link
Member

kwonoj commented Apr 16, 2017

I'm closing this issue for now, haven't got subsequent details of operator to initiate discussion to be included in core sets. If this operator seems need to be included in core operator sets, please refer #2299 and #2524 as starting baseline to include details for discussions.

@kwonoj kwonoj closed this as completed Apr 16, 2017
@passsy
Copy link
Author

passsy commented Apr 16, 2017

Just want to make sure this issue didn't got closed accidentally. It's not about new operators. It's about other base classes besides Observable

  • Observable: 0..N flows, no backpressure
  • Single: a flow of exactly 1 item or an error
  • Completable: a flow without items but only a completion or error signal
  • Maybe: a flow with no items, exactly one item or an error

@kwonoj
Copy link
Member

kwonoj commented Apr 16, 2017

@passsy yes, while attached references are saying only about operators, you can consider same for any other cases like this one, or either removing, changing existing operator behavior as well. There is no big differences of having new operator, or either new base class in perspective of discussing it to add into core set.

@whymarrh
Copy link

whymarrh commented May 12, 2017

If y'all are open to a bit of discussion on the topic, I do think there are use cases for a type analogous to RxJava's Completable:

Represents a deferred computation without any value but only indication for completion or exception.

That said, the workaround isn't too bad right now, one can (assuming the stream is hot) filter all of the values (e.g. .filter(() => true)).

Example use case

In a redux-observable epic, if you want to dispatch an event after some chain of other actions.

A bit of setup using the example they have on their website:

const PING = 'PING';
const PONG = 'PONG';

const ping = () => ({ type: PING });

const pingEpic = action$ =>
  action$.ofType(PING)
    .delay(1000)
    .mapTo({ type: 'PONG' });

const pingReducer = (state = { isPinging: false }, action) => {
  switch (action.type) {
    case 'PING':
      return { isPinging: true };

    case 'PONG':
      return { isPinging: false };

    default:
      return state;
  }
};

Now if you wanted to dispatch an action after count number of PONG actions have occurred:

const START_ROUND_TRIPS = 'START_ROUND_TRIPS';
const END_ROUND_TRIPS = 'END_ROUND_TRIPS';

const endRoundTrip = (count) => ({type: END_ROUND_TRIPS, payload: {count}})

const roundTripEpic = action$ =>
  action$.ofType(START_ROUND_TRIPS)
    .concatMap((action) => Observable.concat(
      Completable.from(action$.ofType(PONG).take(action.payload.count)), // Up for discussion
      Observable.of(endRoundTrip(action.payload.count))
    ))

It's important that the inner observable not actually contain the actions$.ofType(PONG) values because that would re-dispatch those actions. It's arguable whether this is preferable over .filter(() => true) (I think it's a touch more readable) but I do think it is a use case.

@trxcllnt
Copy link
Member

@passsy @whymarrh isn't this already possible w/ the single(), defaultIfEmpty() and ignoreElements() operators?

@whymarrh
Copy link

(I had forgotten about ignoreElements(), that works better than the .filter(() => true), thanks!)

[I]sn't this already possible w/ the single(), defaultIfEmpty() and ignoreElements() operators?

Some combination of those work as a replacement for a hypothetical Completable, yup.

@WowMuchName
Copy link

From a pure technical point of view one might argue that a completeable is unnecessary since an observable can be used for the job.
However when designing an api it is useful to know whether 0, 1 or N objects can be emitted by a stream. While this should be documented in the jsdoc or javadoc, knowing that by looking at the class of stream makes it a lot easier. It is also useful if those classes enforce those cardinality-constraints so you don't accidentally break your api-contract.
As the rx guy in our team I would also like to point out that there is a barrier of entry you tend to forget about when having worked with rx for some time. Having classes that are called completable, single and maybe - even if they are all essentially observables under the hood - is much easier for rx beginners to understand and work with.

@darkyelox
Copy link

You can simple create the objects in next releases, is useful to have them for some cases and also makes the code more readable (knowing for what a Completeable, Single and a Maybe are for)

@ptitjes
Copy link

ptitjes commented Nov 28, 2017

@trxcllnt Just wanted to point out something. Yes, all of this is possible with combinations of single(), defaultIfEmpty() and ignoreElements(). But I guess having types like Single, Maybe and Completable isn't about runtime expressiveness. It is about what it conveys in the type system: why have only void when you can also have null, undefined, never, etc. Whether they should be expressed as classes or type aliases is another problem (I'd bet on type aliases however).

@sawthompson
Copy link

Would it be possible to revisit this? I think @WowMuchName makes some compelling points. Personally I have found that using Observables as Singles, while technically possible, creates ambiguity and leads to bugs.

@jaumard
Copy link

jaumard commented Apr 18, 2018

+1 on this, Single/Maybe and Completable make it more understandable and maintainable by explicitly saying what behavior you'll have. Having just Observable is for me as bad as saying Any on return type of a method, you don't know what you'll have except if you actually look the implementation...

@lock
Copy link

lock bot commented Jun 5, 2018

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 5, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants