mbest / knockout-deferred-updates

Deferred Updates plugin for Knockout <=3.3.0
http://mbest.github.io/knockout-deferred-updates/
134 stars 23 forks source link

Knockout computed update notification sometimes not firing #24

Closed nmehlei closed 9 years ago

nmehlei commented 9 years ago

I am currently investigating a very weird bug in my application which seems to be strongly-related to the ko-deferred-updates v.3.2.0.

When using the newest version, sometimes (in a very hard to reproduce way) either the update notification of a changed computed is not sent or subscribing computed's just ignore said notification. Either way I detect bindings that stay frozen in states, dependent computed's that get corrupted computations because they use old values, etc.

It may be the same for normal observables but since I use more computed's than observables, I did not find such a case with observables in my application yet.

Unfortunately I was unable to find a reproducible way. Used Knockout version is the newest, 3.2.0. This does not happen when using ko-deferred-updates v.3.1.0 (albeit with a small hack to deactivate the version check to use it for ko 3.2.0, which worked perfectly for months) and thus only started to occur since the last update.

mbest commented 9 years ago

Thanks for reporting this. I've come up with an example that reproduces the problem. http://jsfiddle.net/mbest/cq8qp42b/

function ViewModel() {
    var self = this;
    self.x = ko.observable(1);
    self.y = ko.computed(function() {
        return self.x() * 2;
    }).extend({throttle:1000});
    self.update = function() {
        self.y();
    }
}

If update is called after x is changed and before the 1000 ms timeout, the computed never fires a change notification. This example makes it easy to test, but this problem could happen without using throttle if the timing was right.

mbest commented 9 years ago

Here's a much simpler example. http://jsfiddle.net/mbest/33wmc6rn/

function ViewModel() {
    var self = this;
    self.x = ko.observable(1);
    self.y = ko.computed(function() {
        return self.x() * 2;
    });
    self.update = function() {
        self.x(self.x()+1);
        self.y();
    }
}

I'm working on fix now.

nmehlei commented 9 years ago

Awesome! I'll try it out later today, thank you so much.

mbest commented 9 years ago

Did it work for you?

nmehlei commented 9 years ago

Oh, I'm so sorry, forgot to report. Yes it worked perfectly, thanks!