var ViewModel = function () { this.normal = ko.observableArray(); this.throttled = ko.observableArray().extend({ rateLimit: 500 }); this.debounced = ko.observableArray().extend({ rateLimit: { timeout: 500, method: "notifyWhenChangesStop" } }); this.addItems = function() { this.normal.push({}); this.throttled.push({}); this.debounced.push({}); }; this.count = 0; this.delay = 100; this.interval = null; this.go = function() { this.count = 0; this.normal([]); this.throttled([]); this.debounced([]); //on a reset, ensure that everyone is able to notify on their empty state setTimeout(function() { clearInterval(this.interval); this.interval = setInterval(function() { this.count++; this.addItems(); if (this.count === 100) { clearInterval(this.interval); } }.bind(this), this.delay); }.bind(this), 500); }; }; ko.applyBindings(new ViewModel());
<button data-bind="click: go">Start</button> <h1>Normal (<span data-bind="text: normal().length + '%'"></span>)</h1> <ul data-bind="foreach: normal"> <li></li> </ul> <h1>Throttled (<span data-bind="text: throttled().length + '%'"></span>)</h1> <ul data-bind="foreach: throttled"> <li></li> </ul> <h1>Debounced (<span data-bind="text: debounced().length + '%'"></span>)</h1> <ul data-bind="foreach: debounced"> <li></li> </ul>
button { font-size: 2em; } ul { -webkit-margin-before: 0; -webkit-margin-after: 0; -webkit-padding-start: 0; } li { display: inline; padding: 2px; background-color: green; font-size: .7em; }