首页 > 解决方案 > 使用 `jest.useFakeTimers()` 时,为什么 `setImmediate` 不会无限期超时?

问题描述

使用时jest.useFakeTimers(),为什么做setTimeout()setImmediate()行为不同?:

beforeAll(jest.useFakeTimers);
afterAll(jest.useRealTimers);

describe("timer behavior", () => {
  it('times out waiting for a setTimeout', async () => {
    await new Promise(setTimeout);
  });

  it('successfully resolves a setImmediate', async () => {
    await new Promise(setImmediate);
  });
});

这种setTimeout()行为对我来说是有意义的,但为什么一个嘲笑的setImmediate()解决方案像往常一样?

标签: javascriptjestjs

解决方案


setImmediate 和 setTimeout 之间的区别在于 set setImmediate 会在“当前轮询阶段完成后”安排立即执行的回调,而 setTimeout 会安排在“经过 ms 的最小阈值之后”执行回调。

即使超时为 0,setTimeout 仍然依赖于检查时间的流逝,而 setImmediate 无论如何都不依赖于时钟。

因此,使用假计时器时,使用 setTimeout 安排的回调将始终等到模拟时钟滴答声,而使用 setImmediate 安排的回调将立即执行。

如果您查看 Jest 的源代码,它用于 setImmediate 的伪代码只是一个薄包装器,它创建一个可取消的回调并立即调用真正的 setImmediate


推荐阅读