-
Notifications
You must be signed in to change notification settings - Fork 3k
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
toPromise should reject if no value is emitted. #5075
Comments
Related #5072 |
I'd be wary of introducing anything else to |
@cartant, that's an interesting proposal. As far as the observable proposal goes, it might still be a moonshot, so I think RxJS, as a library, should work towards making sure our developer ergonomics make sense. await lastValueFrom(source$);
await source$.lastValue();
await source$.toPromise(); Honestly, they're all a little unpalatable. lol |
This is meant to be a more well-behaved, a better-named, replacement for `toPromise`. Resolves ReactiveX#5075
One reason for my wanting it removed from the protoype, is that I cannot recall using it outside of some tests that I wrote years ago. It seems a little weird to have switched to static, pipeable, tree-shakeable operators, but still have (what ought to be, IMO) a rarely-used method on the prototype. |
This is meant to be a more well-behaved, a better-named, replacement for `toPromise`. Resolves ReactiveX#5075
I tend to agree making this as static method, mostly I would prefer observable itself to be thin enough. |
Decided that we want to go with static methods and deprecate |
I appreciate this is an old thread but I wanted to raise my concerns with using exceptions/rejections for this, especially before v7 hits stable and people begin to rely on these new promise operators ( It's very easy to forget that some code might throw/reject. Ideally, the API would be designed so that the type system won't allow you to forget, so that code path is always handled. The I think there is another solution, though. In This function will return Could we do something similar to this? This solution doesn't have the drawbacks of the other two solutions (returning Going further, |
IMO, this is something that would be better handled in userland - with a function that wraps And regarding |
Consistency is important, agreed! Maybe we could change |
My understanding is that we want to limit breaking changes to types and incorrect behaviours only. Introducing something like
|
Ah, fair enough. I do wonder though if it would better to avoid exceptions for these new operators instead of digging ourselves deeper into that hole for the sake of consistency—it's a trade off. If we use exceptions then it will make the migration more difficult later on, should we decide to move away from using exceptions/rejections in operators. If we use something like a (very tiny) |
Another thing is that with many non-trivial observable sources, there will always be the possibility that the source itself could error and that will need to be dealt with regardless of whether or not an |
Exceptions can happen anywhere, e.g. if the programmer makes a mistake resulting in a Consider this pseudo code where try {
const a = as.map(fn).first();
} catch (error) {} The programmer could make a mistake in Similarly, the same thing could happen with observables (except of course the "exception" would be an error received by the observer): as.map(fn).first().subscribe(
a => {},
error => {}
) In both cases (array and observable), if Programmer mistakes should bubble up as exceptions—but forgetting to handle the case of an empty array/observable when using (I'm focusing on |
@cartant I'm not sure if this conflicts with any previous statements I've made, but I'm not sure we can do that with I mean, it's totally debatable. It's a matter of principal about what we wanted to say |
If you don't want |
Just to clarify, I used |
Closing this because this is the behaviour in the now-released v7. @OliverJAsh I'm not opposed to an approach that does away with throwing/emitting errors, but I think it will have to encompass more of the API than just Anyway, the API now allows for a default value to be returned for empty sources, so it ought to be a little more ergonomic. So I'm closing this. |
In my mind we would just switch out How about I open a new issue to track the idea of migrating operators away from exceptions for non-exceptional scenarios like when an observable is empty? |
Current Behavior
toPromise
will resolve withundefined
if the source observable simply completes without emitting a value.The problem
Promises are a guarantee to a future value. With
toPromise()
we should be saying "this is the last value we've gotten prior to completion". But what we're actually saying is "this might be the last value we've gotten prior to completion". It's semantically unsound, IMO.If the developer wants a guaranteed value from a source, and that value might be
undefined
, there's currently no way for that developer to discern whether or not theundefined
thattoPromise
resolved with was theundefined
from the source, or just happenstance from completion without a value.Proposal
Have
toPromise
reject with anEmptyError
if no value is emitted prior to completion of the source.Optionally we could introduce a
last()
orlastValue()
method toObservable
and deprecatetoPromise
to reduce confusion while migrating to this change, while also being able ot introduce this better semantic sooner.Related: #4993
The text was updated successfully, but these errors were encountered: