了解 Sinon 时钟 `tick` 与 `tickAasync`
Understanding Sinon clock `tick` vs `tickAasync`
我想了解 clock.tick
和 clock.tickAsync
之间的区别以及我应该在哪里使用它们。文档中的解释对我来说不是很清楚,通过查看代码本身,我仍然无法理解应该在何时何地使用每种方法。谁能帮我举个具体的代码示例?
The tickAsync() will also break the event loop, allowing any scheduled promise callbacks to execute before running the timers.
首先,我建议查看 video about event loop。
如果短,tick
和tickAsync
的区别是tick
- 调用定时器同步和tickAsync
是 - 调用定时器 异步 允许在调用定时器
之前执行已解决的承诺
什么是同步。让我们看一下我们要测试的示例代码
function myFunction() {
setTimeout(() => console.log('foo'), 1000)
Promise.resolve().then(() => console.log('zoo'));
console.log('bar')
}
和我们的同步测试代码
it('should test synchronously', () => {
myFunction()
tick(1000); // This would call scheduled timers synchronously ⚠️
console.log('baz')
});
// print 'bar'
// print 'foo'
// print 'baz'
// print 'zoo'
现在让我们看一下相同的测试代码,但 tickAsync
it('should test synchronously', () => {
myFunction()
tickAsync(1000);
console.log('baz')
});
// print 'bar'
// print 'baz'
// print 'zoo'
// print 'foo'
如您所见,打印字符串的顺序发生了变化。
现在是相同的代码,但带有 await
it('should test synchronously', async () => {
myFunction()
await tickAsync(1000);
console.log('baz')
});
// print 'bar'
// print 'zoo'
// print 'foo'
// print 'baz'
要理解顺序改变的原因,您应该了解 micro tasks queue 和常规队列之间的区别。但是如果你看了上面 link 的视频,你应该已经明白了
P.S。
此外,您应该了解 sinon.useFakeTimers();
将在自己的实现中替换 setTimeout
和 setInterval
,从而允许 sinon 完全控制传递给这些函数的计时器
这是一个非常粗略的近似值 sinon tick
& tickAsync
是如何实现的
scheduledTimers = [];
function useFakeTimers() {
global.setInterval = global.setTimeout = (fn) => {
scheduledTimers.push(fn);
}
}
function tick() {
while (scheduledTimers.length) {
scheduledTimers.shift()();
}
}
function tickAsync() {
// Call timers on the next tick
return Promise.resolve().then(() => tick());
}
我想了解 clock.tick
和 clock.tickAsync
之间的区别以及我应该在哪里使用它们。文档中的解释对我来说不是很清楚,通过查看代码本身,我仍然无法理解应该在何时何地使用每种方法。谁能帮我举个具体的代码示例?
The tickAsync() will also break the event loop, allowing any scheduled promise callbacks to execute before running the timers.
首先,我建议查看 video about event loop。
如果短,tick
和tickAsync
的区别是tick
- 调用定时器同步和tickAsync
是 - 调用定时器 异步 允许在调用定时器
什么是同步。让我们看一下我们要测试的示例代码
function myFunction() {
setTimeout(() => console.log('foo'), 1000)
Promise.resolve().then(() => console.log('zoo'));
console.log('bar')
}
和我们的同步测试代码
it('should test synchronously', () => {
myFunction()
tick(1000); // This would call scheduled timers synchronously ⚠️
console.log('baz')
});
// print 'bar'
// print 'foo'
// print 'baz'
// print 'zoo'
现在让我们看一下相同的测试代码,但 tickAsync
it('should test synchronously', () => {
myFunction()
tickAsync(1000);
console.log('baz')
});
// print 'bar'
// print 'baz'
// print 'zoo'
// print 'foo'
如您所见,打印字符串的顺序发生了变化。
现在是相同的代码,但带有 await
it('should test synchronously', async () => {
myFunction()
await tickAsync(1000);
console.log('baz')
});
// print 'bar'
// print 'zoo'
// print 'foo'
// print 'baz'
要理解顺序改变的原因,您应该了解 micro tasks queue 和常规队列之间的区别。但是如果你看了上面 link 的视频,你应该已经明白了
P.S。
此外,您应该了解 sinon.useFakeTimers();
将在自己的实现中替换 setTimeout
和 setInterval
,从而允许 sinon 完全控制传递给这些函数的计时器
这是一个非常粗略的近似值 sinon tick
& tickAsync
是如何实现的
scheduledTimers = [];
function useFakeTimers() {
global.setInterval = global.setTimeout = (fn) => {
scheduledTimers.push(fn);
}
}
function tick() {
while (scheduledTimers.length) {
scheduledTimers.shift()();
}
}
function tickAsync() {
// Call timers on the next tick
return Promise.resolve().then(() => tick());
}