Skip to content

subscribing fails with a function that doesn't have a normal bind() #6783

Closed
@getify

Description

@getify

[Update: the conversation has shifted down-thread, from this OP being about a "broken" subscriber callback, to whether or not there's any merit to being able to opt-out of bind(..)ing, for performance reasons]


Describe the bug

I have a unique situation where I'm trying to subscribe to an observable with a function that has an overridden bind(..), which does something different than normal Function#bind would do. I tried passing that function as a subscription next function, and subscribe(..) either seems to ignore it (silently) or in some other way just fails to ever call it as expected.

Expected behavior

I expected to be able to pass in any function that is normally callable, like fn(..) (or fn.call(..) or fn.apply(..)) and have it work fine as a subscription.

As shown in the reproduction code below, the simple workaround is to wrap my function in an arrow/lambda. That's not awful, but it's annoying and a bit wasteful to have to do so. I'd really like to avoid that.

I wouldn't have expected that subscriber functions must be this-bindable. I read through some documentation and I didn't see such a gotcha listed -- apologies if this is documented and I missed it.

If it's not documented, I think it probably should be!

My argument against the current behavior is, a lot of people probably pass => functions anyway, so Rx is likely not getting much out of trying to bind the this context on those subscription function calls.


But if that behavior is just absolutely required by RxJS, I wonder if there could be some way of opting out that doesn't involve having to wrap my function in an arrow/lambda every time? Perhaps, for example, it could be something like one of these:

rx.subscribe({ _next: myA });   // or some other variation of property name

// or
rx.subscribe({ next: myA, noBind: true });

// or
rx.subscribeNoBind({ next: myA });

It could ALSO possibly be that having a path to opt-out of this binding -- for those like me don't need or want it -- might even be just ever so slightly faster on execution. ;-)

Reproduction code

import { of } from 'rxjs';

function myA(v) { console.log("a",v); }
function myB(v) { console.log("b",v); }

myA.bind = function(){ /*.. something different ..*/ }
myB.bind = function(){ /*.. something different ..*/ }

const rx = of(42);

// does not work
rx.subscribe({ next: myA });

// works fine
rx.subscribe({ next: v => myB(v) });

Reproduction URL

https://stackblitz.com/edit/rxjs-y1wqko

Version

7.5.2

Environment

Node 16

Additional context

The source of these special functions (that don't have a normal behaving bind(..)) is from a library I wrote, and I want users to be able to use them with RxJS as easily as possible.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions