当你扩展一个 observable 时,扩展器通常会用另一个具有所需行为的 observable 包装这个 observable。您可以保留对原始 observable 的引用,这将允许您直接写入它,同时正常公开您的 observable 的节流版本。
例如,
var myObservable = ko.observable('foo');
var myThrottledObservable = myObservable.extend({ throttle: 500 });
myThrottledObservable('bar'); // delayed
myObservable('baz'); // immediate
waiting
在您的特定用例中,不要限制可观察对象,而是限制可outstandingRequests
观察对象并使用waiting
.
var outstandingRequests = ko.observable(0);
// throttled requests for the waiting observable
var throttledOutstandingRequests = outstandingRequests.extend({ throttle: 500 });
// true if any requests are outstanding
var waiting = ko.computed(function() {
return throttledOutstandingRequests() > 0;
};
// These are called when AJAX requests begin or end
function ajaxBegin() {
outstandingRequests(++outstandingRequests());
}
function ajaxEnd() {
outstandingRequests(--outstandingRequests());
}
写入您的outstandingRequests
observable 会立即发生,但您的waiting
observable 将被有效地限制。
或者,我认为更简洁的解决方案是重新实现throttled
扩展器以添加立即更新的能力。
ko.extenders['throttleEx'] = function(target, timeout) {
// Throttling means two things:
// (1) For dependent observables, we throttle *evaluations* so that, no matter how fast its dependencies
// notify updates, the target doesn't re-evaluate (and hence doesn't notify) faster than a certain rate
target['throttleEvaluation'] = timeout;
// (2) For writable targets (observables, or writable dependent observables), we throttle *writes*
// so the target cannot change value synchronously or faster than a certain rate
var writeTimeoutInstance = null;
var throttled = ko.dependentObservable({
'read': target,
'write': function(value) {
clearTimeout(writeTimeoutInstance);
writeTimeoutInstance = setTimeout(function() {
target(value);
}, timeout);
}
});
// add function to set the value directly
throttled['immediate'] = function(value) {
target(value);
};
return throttled;
};
然后使用它:
var waiting = ko.computed(function() {
return outstandingRequests() > 0;
}.extend({ throttleEx: 500 });
// These are called when AJAX requests begin or end
function ajaxBegin() {
outstandingRequests.immediate(++outstandingRequests());
}
function ajaxEnd() {
outstandingRequests.immediate(--outstandingRequests());
}