注意:这个速率限制API是在Knockout 3.1.0中添加的。

通常,更改的observable立即通知其订户,以便依赖于observable的任何计算的observable或绑定都会同步更新。 但是,rateLimit扩展器会导致observable在指定的时间段内抑制和延迟更改通知。 因此,速率限制的observable异步更新依赖关系。

速率限制扩展器可以应用于任何类型的可观察量,包括可观察数组和计算可观察量。 速率限制的主要用例是:

  • 使事情在一定延迟后作出反应
  • 将多个更改合并到单个更新中

如果您只需要组合更新而不添加延迟,则延迟更新提供了一种更有效的方法。

应用速率限制扩展

速率限制支持两种参数格式:

// Shorthand: Specify just a timeout in milliseconds
someObservableOrComputed.extend({ rateLimit: 500 }); // Longhand: Specify timeout and/or method
someObservableOrComputed.extend({ rateLimit: { timeout: 500, method: "notifyWhenChangesStop" } });

方法选项控制通知何时触发,并接受以下值:

  1. notifyAtFixedRate — 未另行指定时的默认值。 通知发生在从第一次更改到可观察者的指定时间段(最初或自上一次通知之后)。

  2. notifyWhenChangesStop — 通知发生在可观察者在指定时间段内没有发生变化之后。 每次可观察到的变化,该定时器被重置,因此如果可观察者连续地改变比超时期间更频繁,则不能发生通知。

示例1:基础示例

考虑下面代码中的observable:

var name = ko.observable('Bert');

var upperCaseName = ko.computed(function() {
return name().toUpperCase();
});

通常,如果您更改名称如下:

name('The New Bert');

upperCase Name将在下一行代码运行之前立即完成。 但是如果你改为使用rateLimit定义名称如下:

var name = ko.observable('Bert').extend({ rateLimit: 500 });

upperCaseName不会在名称更改时立即重新计算,而是在将其新值通知给upperCaseName之前,将等待500毫秒(半秒),然后重新计算其值。 无论在这500ms内名称是多少次更改,upperCaseName只会更新一次最新的值。

示例2:当用户停止输入时执行某些操作

在这个实例中,有一个instantValue observable,当你按下一个键时立即反应。 然后将其封装在delayedValue计算observable中,该observable配置为仅当更改停止至少400毫秒时通知使用notifyWhenChangesStop rate-limit方法。

尝试一下:

Type stuff here:

Current delayed value:

Stuff you have typed:

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延长器比较

如果要使用已弃用的throttle扩展程序迁移代码,则应注意以下方法,即rateLimit扩展程序与throttle扩展程序不同。

使用rateLimit时:

  1. 对可观测量的写入不被延迟; observables值立即更新。 对于可写的计算可观测量,这意味着写函数总是立即运行。

  2. 所有更改通知都会延迟,包括手动调用valueHasMutated时。 这意味着您不能使用valueHasMutated强制速率限制的observable通知未更改的值。
  3. 默认速率限制方法与throttle算法不同。 要匹配throttle行为,请使用notifyWhenChangesStop方法。
  4. 速率限制的计算观察值的评估不受速率限制; 如果你读它的值,它会重新评估。

KnockoutJS 3.X API 第七章 其他技术(4) 速率限制的更多相关文章

  1. KnockoutJS 3.X API 第七章 其他技术(8) 异步错误处理

    注意:本文档适用于Knockout 3.4.0及更高版本. ko.onError Knockout包装内部异步调用,并在抛出原始错误之前查找可选的ko.onError回调以执行(如果遇到异常). 这使 ...

  2. KnockoutJS 3.X API 第七章 其他技术(7) 微任务

    注意:本文档适用于Knockout 3.4.0及更高版本. Knockout的微任务队列 Knockout的微任务队列支持调度任务尽可能快地运行,同时仍然是异步的,努力安排它们在发生I / O,回流或 ...

  3. KnockoutJS 3.X API 第七章 其他技术(6) 使用“fn”添加自定义函数

    有时,您可能会通过向Knockout的核心值类型添加新功能来寻找机会来简化您的代码. 您可以在以下任何类型中定义自定义函数: 因为继承,如果你附加一个函数到ko.subscribable,它将可用于所 ...

  4. KnockoutJS 3.X API 第七章 其他技术(5) 使用其他事件处理程序

    在大多数情况下,数据绑定属性提供了一种干净和简洁的方式来绑定到视图模型. 然而,事件处理是一个常常会导致详细数据绑定属性的领域,因为匿名函数通常是传递参数的推荐技术. 例如: <a href=& ...

  5. KnockoutJS 3.X API 第七章 其他技术(3) 延迟更新

    .example { display: inline-block; padding: 1em; margin-right: 2em; background: #F6F6EF; } 注意:本文档适用于K ...

  6. KnockoutJS 3.X API 第七章 其他技术(2) 使用扩展器来增加可观察量(监控属性)

    Knockout observables提供了支持读取/写入值并在值改变时通知订阅者所需的基本功能. 但在某些情况下,您可能希望向可观察者添加其他功能. 这可能包括通过在可观察者前面放置一个可写的计算 ...

  7. KnockoutJS 3.X API 第七章 其他技术(1) 加载和保存JSON数据

    Knockout允许您实现复杂的客户端交互性,但几乎所有Web应用程序还需要与服务器交换数据,或至少将本地存储的数据序列化. 最方便的交换或存储数据的方式是JSON格式 - 大多数Ajax应用程序今天 ...

  8. KnockoutJS 3.X API 第六章 组件(5) 高级应用组件加载器

    无论何时使用组件绑定或自定义元素注入组件,Knockout都将使用一个或多个组件装载器获取该组件的模板和视图模型. 组件加载器的任务是异步提供任何给定组件名称的模板/视图模型对. 本节目录 默认组件加 ...

  9. KnockoutJS 3.X API 第六章 组件(3) 组件绑定

    组件绑定将指定的组件注入到元素中,并且可选地将参数传递给它. 本节目录 一个例子 API 组件生命周期 备注1:仅限模板组件 备注2:使用没有容器元素的组件 备注3:将标记传递给组件 处置和内存管理 ...

随机推荐

  1. Scrum项目7.0

    队友: 郭志豪:http://www.cnblogs.com/gzh13692021053/ 杨子健:http://www.cnblogs.com/yzj666/ 刘森松:http://www.cnb ...

  2. nodejs之主机不能访问到虚拟机的web服务器

    问题:在主机使用VMware搭建虚拟机,并运行node.但是主机浏览器不能访问 环境:虚拟机使用centos7,网络模式为桥接.主机IP 192.168.1.48  虚拟机IP 192.168.1.5 ...

  3. C++文件操作(fstream)

    C++ 通过以下几个类支持文件的输入输出: ofstream: 写操作(输出)的文件类 (由ostream引申而来) ifstream: 读操作(输入)的文件类(由istream引申而来) fstre ...

  4. 创建WP8试用应用

    参考资料: 创建 Windows Phone 的试用应用 如何在 Windows Phone 应用中实现试用体验 Windows Phone 7 开发 31 日谈——第23日:提供试用版应用程序 对资 ...

  5. iOS 清除缓存

    iOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒.它包含三个文件夹: Documents: 苹果建议将程序中建立的或在程序中浏览到的文件数据保存在该目录下 ...

  6. 使用mybatis-generator生成代码

    文档地址: ​http://mbg.cndocs.tk/index.html ​ 以下是一个简单的配置内容. 一.在maven配置文件中添加mybatis-generator插件 1 2 3 4 5 ...

  7. Jquery.load() 使用

    调用load方法的完整格式是:load( url, [data], [callback] ) url:是指要导入文件的地址. data:可选参数:因为Load不仅仅可以导入静态的html文件,还可以导 ...

  8. C#:获取设备电量相关信息

    更多资源:http://denghejun.github.io [DllImport("kernel32.dll",EntryPoint="GetSystemPowerS ...

  9. The Solution of UESTC 2016 Summer Training #1 Div.2 Problem B

    Link http://acm.hust.edu.cn/vjudge/contest/121539#problem/B Description standard input/output Althou ...

  10. Window.focus()让页面成为当前窗体

    Window.focus()让页面成为当前窗体 最近在弄在线客服的时候,想在收到信息时候让窗体自动弹出到最前,最小化的时候也是弹出到最前.本来以为很麻烦,问了好多人,都不知道,在网上查资料也没有查到. ...