国外炫酷网站,深圳建设门户网站,网络营销课程总结,武冈做网站workLoop是 实现时间切片 和 可中断渲染的核心#xff0c;简要说明如下#xff1a;
// 并发任务的入口function workLoopConcurrent() {// Perform work until Scheduler asks us to yield// 有任务 是否需要中断while (workInProgress ! null !shouldYiel…workLoop是 实现时间切片 和 可中断渲染的核心简要说明如下
// 并发任务的入口function workLoopConcurrent() {// Perform work until Scheduler asks us to yield// 有任务 是否需要中断while (workInProgress ! null !shouldYield()) {performUnitOfWork(workInProgress);}}const scheduler {// 任务放到队列里等待空闲执行taskQueue: [{// 每个任务是个回调的概念, 且回调任务是可中断的callback: workLoopConcurrent}],// 判断: 是否需要中断, 将控制权交给主进程shouldYieldToHost() {// 没有剩余时间if (currentTime deadline) {// 但需要渲染 和 有更高优任务if (needsPaint || scheduling.isInputPending()) {return true; // 中断}// 是否超过 300msreturn currentTime maxYieldInterval;}// 还有剩余时间return false;},// 执行入口可见workLoop() {// 当前第一个任务currentTask taskQueue[0];// 每次 currentTask 退出 就是一个时间切切片while (currentTask ! null) {// 任务没有过期, 但一帧已经无可用时间 或 需要被中断, 则让出主线程// 每一次执行均进行超时检测做到让出主线程。// expirationTime currentTime 任务已过期// hasTimeRemaining :有剩余时间// shouldYieldToHost:是否暂停任务让出主线程if (currentTask.expirationTime currentTime (!hasTimeRemaining || shouldYieldToHost())) {break;}// 表示任务到了过期时间并且有剩余时间来执行没有到达需要浏览器渲染的时候// 那么我们执行任务const callback currentTask.callback;// 拿到任务const continuationCallback callback(didUserCallbackTimeout);// 执行任务// 如果该任务后, 还有连续回调if (typeof continuationCallback function) {// 则保留当前currentTask.callback continuationCallback;} else {// 将currentTask移除该队列pop(taskQueue);}// 更新currentTask,取出任务优先级最高的那个任务currentTask peek(taskQueue);}},}简而言之:
有个任务队列 queue该队列存放可中断的任务。
workLoop对队列里取第一个任务currentTask进入循环开始执行。
如果任务执行完后还有连续的回调则 currentTask.callback continuationCallback
否则移除已完成的任务
当该任务没有时间 或 需要中断 (渲染任务 或 其他高优任务插入等)则让出主线程。
否则执行任务 currentTask.callback()
更新任务currentTask继续循环走起。
这里还涉及更多细节例如:
requestAnimationFrame 计算一帧的空余时间
使用new MessageChannel () 执行宏任务;
优先级;
…
这里不做详细说明。