注意:本文档适用于Knockout 3.4.0及更高版本。

Knockout的微任务队列

Knockout的微任务队列支持调度任务尽可能快地运行,同时仍然是异步的,努力安排它们在发生I / O,回流或重绘之前发生。 它在内部用于Knockout组件以维护异步行为,以及用于安排可观察量的延迟更新。

ko.tasks.schedule(function () {
// ...
});

这将把提供的回调函数添加到微任务队列。 Knockout包括快速任务队列,以FIFO顺序运行任务,直到队列为空。 当第一个任务被调度时,Knockout将使用浏览器的微任务支持来调度flush事件(如果可能)。 这确保了第一个任务和后续任务的行为相似。

可以使用从ko.tasks.schedule返回的句柄值取消微任务。 如果任务已经运行或以前已取消,则取消不执行任何操作。

var handle = ko.tasks.schedule(/* ... */);
ko.tasks.cancel(handle);

错误处理

如果任务抛出异常,它不会中断任务队列,这将继续,直到它是空的。 异常将被推迟到稍后的事件,并可以使用ko.onError或window.onerror处理。

递归任务限制

由于Knockout处理微任务队列直到它为空,而不会导致外部事件,许多或冗长的任务可能会导致浏览器页面变得无响应。 如果检测到高级别的递归,则通过取消所有剩余的任务,Knockout可以防止无限递归。 例如,以下将最终停止并抛出一个错误:

function loop() {
ko.tasks.schedule(loop);
}
loop();

实施

当第一个任务被调度时(最初和之前的flush事件已经完成),Knockout将调度一个flush事件来处理微任务队列。 如果可能,它将尝试使用浏览器自己的微服务功能。 在现代浏览器中,它将使用DOM变异观察器,在旧版本的Internet Explorer中,它将使用<script> onreadystatechange事件。 这些方法允许它在任何回流或重绘之前开始处理队列。 在其他浏览器中,它将恢复使用setTimeout。

高级队列控制

Knockout提供了一些高级方法来控制何时处理微任务队列。 如果您想将Knockout的微服务系统与另一个库集成或者添加对其他环境的支持,这些功能非常有用。

  • ko.tasks.runEarly() — 调用此方法根据需要立即处理当前微任务队列,直到它为空。 除了库集成,您可以使用此方法,如果您有代码调度一些任务,但随后需要同步处理这些任务的影响。

  • ko.tasks.scheduler — 覆盖此方法以重新定义或扩充Knockout如何计划事件以处理和刷新队列。 当第一个任务被调度时,Knockout调用此方法,因此它必须调度事件并立即返回。 例如,如果您的应用程序在Node.js中运行,您可能更喜欢对flush事件使用process.nextTick:ko.tasks.scheduler = process.nextTick ;.

KnockoutJS 3.X API 第七章 其他技术(7) 微任务的更多相关文章

  1. KnockoutJS 3.X API 第七章 其他技术(4) 速率限制

    注意:这个速率限制API是在Knockout 3.1.0中添加的. 通常,更改的observable立即通知其订户,以便依赖于observable的任何计算的observable或绑定都会同步更新. ...

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

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

  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. 苹果mac电脑中brew的安装使用及卸载详细教程

    brew 又叫Homebrew,是Mac OSX上的软件包管理工具,能在Mac中方便的安装软件或者卸载软件, 只需要一个命令, 非常方便 brew类似ubuntu系统下的apt-get的功能 安装br ...

  2. [转]MSI安装程序中的文件替换

    原文链接:http://teach.hanzify.org/article/652-1233562028.html 前言 最近有汉化朋友问起如何不重新制作MSI文件,而直接用汉化好的文件替换MSI安装 ...

  3. ASP.NET MVC3中Controller与View之间的数据传递

    在ASP.NET MVC中,经常会在Controller与View之间传递数据,因此,熟练.灵活的掌握这两层之间的数据传递方法就非常重要.本文从两个方面进行探讨: 一.  Controller向Vie ...

  4. HashMap的内部实现机制,Hash是怎样实现的,什么时候ReHash

    1.HashMap的内部实现机制 HashMap是对数据结构中哈希表(Hash Table)的实现,Hash表又叫散列表.Hash表是根据关键码Key来访问其对应的值Value的数据结构,它通过一个映 ...

  5. 一致性hash算法详解

    转载请说明出处:http://blog.csdn.net/cywosp/article/details/23397179     一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT) ...

  6. js中substr,substring,indexOf,lastIndexOf的用法小结

    第一组:str.substr(start,length) 和 str.substring(start,end) 定义: str.substr(start,length) substr(start,le ...

  7. OpenSSL 1.0.2e 3 Dec 2015

    目录: 1,交叉编译openssl 2,win32  vc9 编译 openssl 1,交叉编译openssl [原]交叉编译openssl不修改Makefile的方法 http://blog.chi ...

  8. 9_bootstrap less 移动端

    chrome,firefox提供了"Device Emulation"功能,可模拟常见的各种浏览设备 android ADT或ios Xcode附带的设备模拟器,或第三方在线测试工 ...

  9. 用Node.js发送邮件

    本文讲的是用Node.js通过一个开启smtp的已有的邮箱账号发送邮件,而不是如何创建一个邮件服务器 开启smtp服务 首先要去要使用的邮箱中设置开启smtp,才能正常发送邮件 这边以163邮箱为例 ...

  10. mysql获取自增长插入行的ID

    insert into {14}.SEGMENT(CODE_STARTPOINTID,CODE_STARTFIR,CODE_TYPE_START,CODE_ENDPOINTID,CODE_ENDFIR ...