For some reason my sorted method here in conjunction with ratelimit is causing an endless loop. I am not sure why it won't stop being hit. If I remove the ratelimit or the sorted there is no endless loop, but if I use both it won't stop.
function Unscheduled() {
var self = this;
self.games = ko.observableArray([]).extend({
sorted: function(l, r) {
return l.length > r.length ? -1 : 1;
},
rateLimit: { timeout: 0, method: "notifyWhenChangesStop" }});
self.changes = ko.observable(0);
self.games.subscribe(function (changes) {
console.log('Array Hit');
self.changes(self.changes()+1);
}, null, "arrayChange");
self.games.push('test');
self.addRemove = function() {
self.games.remove('test1');
self.games.push('test');
}
}
ko.extenders.sorted = function (obs, sortFunction) {
ko.computed(function () {
console.log('sorting');
obs.sort(sortFunction)();
});
};
ko.applyBindings(new Unscheduled());
<script src="https://exposureevents.com/scripts/knockout-3.5.0.min.js"></script>
<div data-bind="text: changes">
</div>
<button data-bind="click: addRemove">
Add/Remove
</button>
Seems that the issue is related to sort
method of observableArray
. I guess when using that method it generates a change notification then it tries to sort again and goes in this forever loop. When using sort
on "raw" array there is no such behavior:
function Unscheduled() {
var self = this;
self.games = ko.observableArray([]).extend({
sorted: function(l, r) {
// return l.length > r.length ? -1 : 1;
return l - r;
},
rateLimit: { timeout: 0, method: "notifyWhenChangesStop" }});
self.changes = ko.observable(0);
self.games.subscribe(function (changes) {
console.log('Array Hit');
self.changes(self.changes()+1);
}, null, "arrayChange");
// self.games.push('test');
self.games.push(0);
self.addRemove = function() {
// self.games.remove('test1');
// self.games.push('test');
self.games.push(Math.random() * 10000 | 0);
}
self.gamesText = ko.pureComputed(() => self.games.reversed().join('\n'));
}
ko.extenders.sorted = function (obs, sortFunction) {
ko.computed(function () {
console.log('sorting');
// obs.sort(sortFunction)();
obs().sort(sortFunction);
});
};
ko.applyBindings(new Unscheduled());
<script src="https://exposureevents.com/scripts/knockout-3.5.0.min.js"></script>
<div data-bind="text: changes">
</div>
<button data-bind="click: addRemove">
Add/Remove
</button>
<pre data-bind="text: gamesText"></pre>