代码之家  ›  专栏  ›  技术社区  ›  marzelin

长时间运行的超时回调阻止执行requestAnimationFrame回调

  •  0
  • marzelin  · 技术社区  · 6 年前

    Jake Archibald talk about event loop 了解到浏览器中有3个队列:

    • 微任务队列

    在执行项目时表现不同。

    回调队列一次执行一个回调,这意味着在执行回调之后,浏览器会在继续下一个回调之前检查是否还有其他事情要做(比如重新呈现页面)。

    动画队列用于 requestAnimationFrame 回调,它还执行它的项,直到队列中除了添加到当前执行的回调中的回调(这些回调在下一帧执行)之外,其余的都是空的。

    我想检查一下,并创建了一个递归调用的脚本 请求动画帧 排队等待50次超时回调,阻塞主线程15毫秒。

    for (let i = 0; i < 50; i++) {
      setTimeout(() => {
        block(15);
        console.log(`timeout ${i}`)
      })
    }
    
    const startDate = Date.now();
    function raf() {
      requestAnimationFrame((x) => {
        if (Date.now() < startDate + 1000) {
          console.log(`raf ${x}`)
          raf();
        }
      })
    }
    
    raf();
    
    
    
    function block(ms) {
      const startDate = Date.now();
      while (Date.now() < startDate + ms) { }
    }

    现场演示: https://stackblitz.com/edit/js-xdpbbb?file=index.js

    因为块时间大致等于帧之间的时间(60fps给出16.666ms),所以我希望raf和超时回调之间会出现交织模式。但结果却完全不同:

    results

    如您所见,在raf回调之间大约有10个超时回调,需要大约150毫秒才能完成。为什么不是这样:

    1. 动画cb
    2. 超时cb
    3. ?
    0 回复  |  直到 6 年前