一些异步事件
window.setImmediate
该方法用来把一些需要长时间运行的操作放在一个回调函数里,在浏览器完成后面的其他语句后,就立刻执行这个回调函数,
1
2
3 > var immediateID = setImmediate(func, [param1, param2, ...]);
> var immediateID = setImmediate(func);
>
immediateID 是这次setImmediate方法设置的唯一ID,可以作为 window.clearImmediate 的参数.
func 是将要执行的回调函数
参数param1 param2 …都会直接传给函数func
window.clearImmediate 用来取消通过setImmediate设置的将要执行的语句
与setTimeout
1 | setTimeout(() => { |
setImmediate()设计为在当前 轮询 阶段完成后执行脚本。setTimeout()计划在毫秒的最小阈值经过后运行的脚本。
process.nextTick
无论事件循环的当前阶段如何,都将在当前操作完成后处理 nextTickQueue
process.nextTick()在同一个阶段立即执行。setImmediate()在以下迭代或 ‘tick’ 上触发事件循环。
使用时机:
- 允许用户处理错误,清理任何不需要的资源,或者在事件循环继续之前重试请求。
- 有时在调用堆栈已解除但在事件循环继续之前,必须允许回调运行。
useMutationObserver
MutationObserver接口提供了监视对DOM树所做更改的能力。它被设计为旧的Mutation Events功能的替代品,该功能是DOM3 Events规范的一部分。
构造函数 MutationObserver()
创建并返回一个新的 MutationObserver 它会在指定的DOM发生变化时被调用。
很多框架和库都会使用类似下面函数:
1 | function flush() { |
使用Mutation事件可以异步执行操作(例子中的flush函数),一是可以尽快响应变化,二是可以去除重复的计算
异步
一个🌰看看, 这些异步是怎么执行的:
1 | console.log('start') |
任务
事件轮训是实现异步的一种方式
任务
一个事件轮训有一个或多个任务队列
每当要执行一个任务时, 必须将这个任务添加到相应的事件轮训队列中
每一个任务都来自于特定的任务源, 被添加到特定的任务队列
任务源
任务源种类:
- DOM操作任务源
- 用户交互任务源
- 网络任务源
- history traversal任务源
task任务源非常宽泛,比如ajax的onload,click事件,基本上我们经常绑定的各种事件都是task任务源,还有数据库操作(IndexedDB ),需要注意的是setTimeout、setInterval、setImmediate也是task任务源。
总结来说task任务源:
setTimeout
setInterval
setImmediate
I/O
UI rendering
微任务
每一个事件轮训, 都有一个微任务队列, 微任务会被排进微任务队列
微任务有两种: 1.孤立回调微任务 2.复合微任务(不做考虑)
microtask 队列和task 队列有些相似,都是先进先出的队列,由指定的任务源去提供任务,不同的是一个
event loop里只有一个microtask 队列。
通常认为是microtask任务源有:
- process.nextTick
- promises
- Object.observe
- MutationObserver