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

allow long subscriber chains #359

Closed
wants to merge 2 commits into from
Closed

allow long subscriber chains #359

wants to merge 2 commits into from

Conversation

haberman
Copy link

@haberman haberman commented Mar 5, 2012

This allows subscriber chains to be very long
without stack overflow. This is only done for
the default event; could probably be done for
"beforeChange" also, but would be a more
intrusive code change.

This change passes all tests in my browser
(Chrome).

See: #358

This allows subscriber chains to be very long
without stack overflow.  This is only done for
the default event; could probably be done for
"beforeChange" also, but would be a more
intrusive code change.
@haberman
Copy link
Author

haberman commented Mar 7, 2012

Ping?

@haberman
Copy link
Author

Ping? This change is relatively short and passes all tests (including a new test). Please let me know if there's anything I can do to make this change easier to accept.

@mbest
Copy link
Member

mbest commented Mar 11, 2012

We're currently finishing up work on version 2.1. Afterwards, we'll be able to go through the waiting issues and pull requests.

@haberman
Copy link
Author

Great, thanks for the update.

@mbest
Copy link
Member

mbest commented May 11, 2012

I haven't yet looked out your code in detail, but this will be on our list of items for version 2.2. Other possible implementations include @sciolizer's De-duping calls to evaluateImmediate, or parts of my deferred updates plugin.

@haberman
Copy link
Author

Great! I'm happy with anything that passes my test case with good efficiency. If you do go with either of the other solutions, please do test it with my test case.

@SteveSanderson
Copy link
Contributor

Needs to be reviewed in detail for any possible side-effects, but in principle, this sounds like a worthy improvement. I'd be pleased to have it in 2.2.

Thanks Haberman!

@haberman
Copy link
Author

Hi there, it looks like you haven't gotten a chance to fold this change into knockout? I tried my test case with the latest repo and it is still failing with stack overflow.

Anything I can do to help this change get accepted?

Thanks,
Josh

@mbest
Copy link
Member

mbest commented Jun 27, 2013

Here's my version of this that I just added to my Deferred Updates plugin:

var oldnotifySubscribers = ko.subscribable.fn.notifySubscribers, notifyQueue;
ko.subscribable.fn.notifySubscribers = function (valueToNotify, event) {
    if (event === 'change' || event === 'dirty' || event === undefined) {
        if (!notifyQueue) {
            try {
                notifyQueue = [];
                oldnotifySubscribers.call(this, valueToNotify, event);
                if (notifyQueue.length) {
                    for (var i = 0, n; n = notifyQueue[i]; i++) {
                        oldnotifySubscribers.call(n.object, n.value, n.event);
                    }
                }
            } finally {
                notifyQueue = null;
            }
        } else {
            notifyQueue.push({
                object: this,
                value: valueToNotify,
                event: event
            });
        }
    } else {
        oldnotifySubscribers.call(this, valueToNotify, event);
    }
};

@mbest
Copy link
Member

mbest commented Aug 31, 2013

The code I attached above for notifySubscribers uses a queue/loop instead of recursion. It can be used in any application that runs into "too much recursion" errors. I'm hesitant to make this method the default behavior in Knockout, though, because it's more complicated than recursion and makes it hard to debug dependencies.

As a compromise, I've come up with some changes (#1088) that provide a 100%+ increase in the maximum dependency depth.

mbest referenced this pull request Sep 11, 2015
…four function call levels. Also reduce stack overhead by not using "call" in computed unless needed.
@brianmhunt
Copy link
Member

@haberman – If you have a look at the comments linked to this issue, you'll note that the plan is, at the moment, to have this problem persist on legacy Firefox, for two reasons:

  1. One can work around this with deferred updates, which is available as a plugin for KO 3.3 and before, and integrated as of (forthcoming) 3.4
  2. The problem only exhibits on old versions of Firefox (versions 10 to 23)

The patch you proposed certainly looks to work, but it adds some complexity and does not extend to other event types that may also be affected.

On that basis I'll close this issue, but please comment if you think we're missing something important here and we can certainly discuss/re-open.

Sorry it took so long to get to this @haberman . I hope you found a workaround in the mean time!

Cheers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants