-
Notifications
You must be signed in to change notification settings - Fork 3k
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
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
Can't repeat or retry Observable.bindCallback and Observable.bindNodeCallback #1401
Comments
I see what you mean. It's probably a name thing. Should it have been named ... in a few weeks, we're locking these names in stone until another major, which hopefully won't happen for a while. |
I'd really like to see this fixed. |
Not me. AFAIK go ahead. |
ignore me. my knowledge of rxjs is rapidly increasing. |
I am new on this, but i think i have the same issue. This code is called only once:
But this code is called many many times
How can i fixed ? |
@vvenegasv This issue is a discussion about |
@kwonoj Ok, you are right, this is an event. I did it like this, because with "fromEvent" don't work at all. I was thinking that is because it's not a standard event. Excuse me if my question is silly, but i want to know if i attach an event with bindCallback method, it will be raised everytime? or only once? PS: Sorry for my bad english, i wrote the best i can. |
no worries, it is no silly at all 👍
As I think your case is not tied to this issue, I'd like to suggest to either create new issue if you think current RxJS behavior is problematic, or use SO (http://stackoverflow.com/questions/tagged/rxjs5) for general questions. |
@kwonoj Yes you are right. Thanks a lot! :) |
I too find it very odd that calling subscribe() on the Observable created by bindCallback() does not re-trigger the callback. This behavior completely breaks otherwise normal repeat/retry logic in the midst of a larger Observable sequence. I always have to remember to wrap the bindCallback() in defer() or something similar to get it to trigger again -- which seems unintuitive and is often forgotten. Just like with any "normal" Observable, the default expectation should be that calling subscribe() will re-do the work. IMO, that would be the Least Surprising thing to happen. If one desires to share/cache work, then publish() or some other technique can be used (which would also then serve to explicitly document the intended behavior). |
@mattflix, @trxcllnt el al: There's a couple things to discuss here:
I think 1 is an issue. We should be able to retry or replay them, or we should rename this to 2, on the other hand is stickier. This method was created to model Rx 4's Thoughts? |
I am also for bringing back I would recommend renaming If it were me, I would just nix On related question... why was the |
Thought I would chime in with my thoughts (and reawaken this thread). I'm surprised that Gonna have to use something other than |
@larssn wrapping in |
@trxcllnt ... well if we want to "fix" this, we could propose a new method. The one that exists is largely to honor legacy behavior from RxJS 4. 🤷♂️ |
IIRC, we even named it "bind" to make it sound more like it was locked in to one result and done. |
@trxcllnt Thanks, I ended up cannibalising the source, and stripped out the subject. Maybe call it |
Is it possible to revisit this discussion, now that we're in RxJS6? |
I see a lot of people are proposing to use
The problem with this, is that you attach plenty of You should use bindCallback if it's a one event thing. Something like Now, if you are about to use a
I think there is just a misconception about this |
@jsgoupil yes, |
What is the recommended solution for this? I've been battling with it all day, thinking it was because I still have no idea wtf I'm doing with RX 🥴. I have a codesandbox where I've been trying to figure this out here (link) function fakeSend(
task: string,
cb: (err: Error | null, result?: boolean) => void
) {
console.log("fakesend", task);
setTimeout(() => {
const hasError = Math.random() < 0.5;
const res = Math.random() < 0.5;
console.log(hasError ? "hasError" : `responding with ${res}`);
if (hasError) {
return cb(new Error("error"));
}
return cb(null, res);
}, 100);
}
const boundSend = bindNodeCallback(fakeSend);
const subject = new Subject<string>();
subject
.pipe(
mergeMap((v) => boundSend(v)),
tap((res) => {
console.log("res", res);
if (!res) throw new Error("did not send");
}),
retryWhen((e) => e.pipe(delay(100)))
)
.subscribe();
subject.next("test1");
subject.next("test2");
subject.next("test3");
subject.next("test4"); The only way I've been able to get it to refire is by doing this: subject.subscribe((task) => {
of(task).pipe(
mergeMap((v) => boundSend(v)),
tap((val) => {
if (!val) throw new Error("Did not send");
}),
retryWhen((errs) => errs.pipe(delay(300)))
).subscribe();
}); But that doesn't seem right at all. Thank you :) |
@chanced you could bind it inside your mergeMap. |
@benlesh Not sure what I'm missing, is this right? const subject = new Subject<string>();
subject
.pipe(
mergeMap(res => bindNodeCallback(fakeSend)(res)),
tap(res => {
if (!res) throw new Error("did not send");
}),
retryWhen(e => e.pipe(delay(100)))
)
.subscribe(); Because that's not re-executing for me. https://codesandbox.io/s/youthful-wave-u5bhx?file=/src/index.ts |
Before I found this thread, I had posted over on stack. I recently got a really great answer. incase anyone runs into this issue in the future. also @benlesh as an aside, I really hope I didn't come across as snarky. I just reread what I wrote and went "aarg that sounded rude" but that wasn't my intention at all. I apologize if it came across that way. |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
Observable.bindCallback and Observable.bindNodeCallback create internal AsyncSubjects that live forever after the first subscription, which means we can't retry or repeat these Observables.
I understand this is how it worked before, but that behavior seems to be incidentally caused by the old
multicast
behavior disallowing retrying and repeating. Does anybody else think we should allow retrying/repeating, or at least allow end users to override the multicast behavior?The text was updated successfully, but these errors were encountered: