一般,更改的observable當即通知其訂戶,以便依賴於observable的任何計算的observable或綁定都會同步更新。 可是,rateLimit擴展器會致使observable在指定的時間段內抑制和延遲更改通知。 所以,速率限制的observable異步更新依賴關係。 算法
速率限制擴展器能夠應用於任何類型的可觀察量,包括可觀察數組和計算可觀察量。 速率限制的主要用例是: 數組
若是您只須要組合更新而不添加延遲,則延遲更新提供了一種更有效的方法。 app
速率限制支持兩種參數格式:異步
// Shorthand: Specify just a timeout in milliseconds someObservableOrComputed.extend({ rateLimit: 500 }); // Longhand: Specify timeout and/or method someObservableOrComputed.extend({ rateLimit: { timeout: 500, method: "notifyWhenChangesStop" } });
方法選項控制通知什麼時候觸發,並接受如下值: 函數
notifyAtFixedRate
— 未另行指定時的默認值。 通知發生在從第一次更改到可觀察者的指定時間段(最初或自上一次通知以後)。this
notifyWhenChangesStop
— 通知發生在可觀察者在指定時間段內沒有發生變化以後。 每次可觀察到的變化,該定時器被重置,所以若是可觀察者連續地改變比超時期間更頻繁,則不能發生通知。spa
考慮下面代碼中的observable:code
var name = ko.observable('Bert'); var upperCaseName = ko.computed(function() { return name().toUpperCase(); });
一般,若是您更更名稱以下:blog
name('The New Bert');
upperCase Name將在下一行代碼運行以前當即完成。 可是若是你改成使用rateLimit定義名稱以下:ci
var name = ko.observable('Bert').extend({ rateLimit: 500 });
upperCaseName不會在名稱更改時當即從新計算,而是在將其新值通知給upperCaseName以前,將等待500毫秒(半秒),而後從新計算其值。 不管在這500ms內名稱是多少次更改,upperCaseName只會更新一次最新的值。
在這個實例中,有一個instantValue observable,當你按下一個鍵時當即反應。 而後將其封裝在delayedValue計算observable中,該observable配置爲僅當更改中止至少400毫秒時通知使用notifyWhenChangesStop rate-limit方法。
嘗試一下:
Type stuff here:
Current delayed value:
UI源碼:
<p>Type stuff here: <input data-bind='textInput: instantaneousValue' /></p> <p>Current delayed value: <b data-bind='text: delayedValue'> </b></p> <div data-bind="visible: loggedValues().length > 0"> <h3>Stuff you have typed:</h3> <ul data-bind="foreach: loggedValues"> <li data-bind="text: $data"></li> </ul> </div>
視圖模型源碼:
function AppViewModel() { this.instantaneousValue = ko.observable(); this.delayedValue = ko.pureComputed(this.instantaneousValue) .extend({ rateLimit: { method: "notifyWhenChangesStop", timeout: 400 } }); // Keep a log of the throttled values this.loggedValues = ko.observableArray([]); this.delayedValue.subscribe(function (val) { if (val !== '') this.loggedValues.push(val); }, this); } ko.applyBindings(new AppViewModel());
對於計算的observable,當計算的observable的依賴性之一改變而不是其值改變時,觸發速率限制定時器。 計算的observable不會從新求值,直到實際須要它的值 - 在發生更改通知的超時時間段以後,或直接訪問計算的可觀察值時。 若是須要訪問計算的最近評估的值,可使用peek方法執行此操做。
當any observable的值是原始值(數字,字符串,布爾值或null)時,只有當observable的依賴項設置爲實際上與以前不一樣的值時,纔會通知它的依賴項。 所以,原始值的速率限制可觀察量只有當它們的值在超時週期結束時實際上不一樣時才通知。 換句話說,若是原始值的速率限制的observable被改變爲新的值,而後在超時時間段結束以前改變回原始值,則不會發生通知。
若是要確保始終通知訂閱者更新,即便該值相同,除了rateLimit以外,還要使用notify擴展器:
myViewModel.fullName = ko.computed(function() { return myViewModel.firstName() + " " + myViewModel.lastName(); }).extend({ notify: 'always', rateLimit: 500 });
Knockout 3.4.0版本增長了對延遲更新的支持,經過使通知和更新異步,它的工做方式相似於速率限制。 可是,不是使用定時延遲,而是在執行I / O,迴流或重繪以後,在當前任務以後儘快處理延遲更新。 若是要升級到3.4.0而且使用速率限制超時(例如,0毫秒)的代碼,則能夠修改成使用延遲更新:
ko.computed(function() { // .... }).extend({ deferred: true });
若是要使用已棄用的throttle擴展程序遷移代碼,則應注意如下方法,即rateLimit擴展程序與throttle擴展程序不一樣。
使用rateLimit時: