Skip to content

Commit

Permalink
Use notifySubscribers instead of subscribe to do rate-limiting.
Browse files Browse the repository at this point in the history
  • Loading branch information
mbest committed Dec 25, 2013
1 parent 62b4310 commit ace739b
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 33 deletions.
2 changes: 1 addition & 1 deletion spec/asyncBehaviors.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ describe('Rate-limited', function() {
expect(notifySpy).toHaveBeenCalledWith('b');
});

it('Should delay notifications if subscription is rate-limited', function() {
xit('Should delay notifications if subscription is rate-limited', function() {
var subscribable = new ko.subscribable();
// First subscription is rate-limited
var notifySpy1 = jasmine.createSpy('notifySpy1');
Expand Down
10 changes: 3 additions & 7 deletions src/subscribables/dependentObservable.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,14 +185,10 @@ ko.dependentObservable = function (evaluatorFunctionOrOptions, evaluatorFunction
// Replace the limit function with one that delays evaluation as well.
var originalLimit = dependentObservable['limit'];
dependentObservable['limit'] = function(limitFunction, funcOptions) {
originalLimit.apply(this, arguments);
var finish = limitFunction(evaluateImmediate, funcOptions);
originalLimit.call(this, limitFunction, funcOptions);
dependentObservable._evalRateLimited = function() {
if (dependentObservable.hasSubscriptionsForEvent('change')) {
dependentObservable["notifySubscribers"](dependentObservable);
} else {
finish(dependentObservable);
}
dependentObservable._storePreviousValue(_latestValue);
dependentObservable._notifyRateLimited(dependentObservable);
}
};

Expand Down
63 changes: 38 additions & 25 deletions src/subscribables/subscribable.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,6 @@ ko.subscription.prototype.dispose = function () {
this.isDisposed = true;
this.disposeCallback();
};
ko.subscription.prototype['limit'] = function (limitFunction, funcOptions) {
var self = this,
target = self.target,
originalCallback = self.callback,
previousValue = target.peek ? target.peek() : undefined,
pendingValue;

var finish = limitFunction(function () {
if (pendingValue === target) {
pendingValue = target();
}
if (!self.isDisposed && target.isDifferent(previousValue, pendingValue)) {
originalCallback(previousValue = pendingValue);
}
}, funcOptions);

self.callback = function(value) {
pendingValue = value;
finish(target, value);
};
};

ko.subscribable = function () {
ko.utils.setPrototypeOfOrExtend(this, ko.subscribable['fn']);
Expand All @@ -50,8 +29,8 @@ var ko_subscribable_fn = {
ko.utils.arrayRemoveItem(self._subscriptions[event], subscription);
});

if (event === defaultEvent && self._limitFunction) {
subscription['limit'](self._limitFunction, self._limitFuncOptions);
if (event === defaultEvent && self._notifyRateLimited && self.peek) {
self.peek();
}

if (!self._subscriptions[event])
Expand All @@ -78,8 +57,42 @@ var ko_subscribable_fn = {
},

'limit': function(limitFunction, funcOptions) {
this._limitFunction = limitFunction;
this._limitFuncOptions = funcOptions;
var self = this, isPending, previousValue, pendingValue;

if (!self._origNotifySubscribers) {
self._origNotifySubscribers = self["notifySubscribers"];
self["notifySubscribers"] = function(value, event) {
if (!event || event === defaultEvent) {
this._notifyRateLimited(value);
} else {
if (event === 'beforeChange') {
this._storePreviousValue(value);
}
this._origNotifySubscribers(value, event);
}
};
}

var finish = limitFunction(function() {
if (pendingValue === self) {
pendingValue = self();
}
isPending = false;
if (self.isDifferent(previousValue, pendingValue)) {
self._origNotifySubscribers(previousValue = pendingValue);
}
}, funcOptions);

self._notifyRateLimited = function(value) {
isPending = true;
pendingValue = value;
finish(self);
};
self._storePreviousValue = function(value) {
if (!isPending) {
previousValue = value;
}
};
},

hasSubscriptionsForEvent: function(event) {
Expand Down

0 comments on commit ace739b

Please sign in to comment.