首页 > 解决方案 > 为什么 JSDOM 与 Sinon 假定时器一起使用时会进入无限循环?

问题描述

使用最新的 JSDOM (11.6.0),当与 Sinon 的假计时器一起使用时,我得到一个无限循环。

const sinon = require('sinon');

sinon.useFakeTimers();
require('jsdom'); // This line creates an infinite loop

我怎样才能避免这个无限循环?

标签: node.jssinonjsdom

解决方案


这是由新的 Performance API 引起的。

该实现使用 Date.now() 来校准时钟。这是功能:

// This function assumes the clock is accurate.
function calculateClockOffset() {
  const start = Date.now();
  let cur = start;
  while (cur === start) {
    cur = Date.now();
  }
  ...
}

来源,请注意此代码不在 JSDOM 中,而是在其依赖项之一 w3c-hr-time 中)

当你运行时sinon.useFakeTimers();,它会模拟Date.now()总是返回相同的值,因此上面的代码创建了一个无限循环。

解决方法是不模拟Date,只有 setTimeout/setInterval 函数:

// Sinon 2.x
sinon.useFakeTimers('setTimeout', 'clearTimeout', 'setInterval', 'clearInterval');

// Sinon 3.x or higher
sinon.useFakeTimers({toFake:['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval']});

推荐阅读