最近一直在做 LeetCode
题解的相关输出,
有的小伙伴可能会有疑惑,学了算法后,在前端中有哪些地方用到了算法呢?
今天我们就来聊一聊 React
中是如何利用堆维护任务队列的。
业务场景
React
中有很多任务,
例如 用户点击、用户输入以及 setState
等等,而这些任务又有优先级的区分。
比如用户的点击和输入,肯定是高优先级任务,要优先响应,
而 load
以及 animation
事件的优先级肯定要低一些。
如果队列中有了一些低优先级任务,此时新进来的高优先级任务就要插队执行,那么 React
是如何管理这些任务的呢?
源码地址
在 React
源码中有目录 packages/scheduler
,该目录就是 React
任务调度模块相关。
该目录 src
下
Scheduler.js 实现了任务调度相关逻辑
SchedulerMinHeap.js 实现了堆
小顶堆任务调度
React
会有一系列规则定义每个任务的优先级,最后的表现就是 React
会将每个任务包装为一个任务对象 newTask 319行,该对象会存在两个属性 id
和 sortIndex
,
其中 sortIndex
标识当前任务的优先级, id
标识每个任务的先后顺序。
React
中存放任务的数组 taskQueue
会被模拟为一个小顶堆,
该小顶堆的 compare
逻辑是优先比较 sortIndex
(即任务的优先级),
如果 sortIndex
相同,则比较 id
(即任务创建的先后顺序)。
因为堆的性质是维护一个最值在堆顶,所以每次堆顶任务(对应任务数组中的第一个元素)就是当前任务队列中优先级最高的任务,这样只需要每次获取堆顶任务执行即可。
堆顶任务取出之后,只需要对小顶堆进行弹堆操作后自上向下的平衡调整,则堆顶又维护了当前任务队列中优先级最高的任务。
这样通过堆维护任务队列,每次获取优先级最高的任务的时间复杂度是 O(1)
的,插入和弹出操作后的平衡调整时间复杂度是 O(logn)
的,整体是非常高效的。
end
以上就是堆在 React
任务调度中的应用,你学会了吗?