Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions packages/vtable/__tests__/debounce.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { debounce } from '../src/tools/debounce';

jest.mock('@src/vrender', () => ({ vglobal: {} }));

describe('debounce', () => {
test('waits for the remaining delay after a call during the debounce window', () => {
let now = 1000;
const timers: { callback: () => void; delay: number }[] = [];
const callback = jest.fn();
jest.spyOn(Date, 'now').mockImplementation(() => now);
jest.spyOn(globalThis, 'setTimeout').mockImplementation((handler, delay) => {
timers.push({ callback: handler as () => void, delay: delay as number });
return timers.length as any;
});

try {
const debounced = debounce(callback, 100);
debounced('first');
now = 1050;
debounced('latest');

now = 1100;
timers.shift()!.callback();
expect(callback).not.toHaveBeenCalled();
expect(timers[0].delay).toBe(50);

// 提前触发时仍等待最后 1ms,避免过早调用用户回调。
now = 1149;
timers.shift()!.callback();
expect(callback).not.toHaveBeenCalled();
expect(timers[0].delay).toBe(1);

now = 1150;
timers.shift()!.callback();
expect(callback).toHaveBeenCalledTimes(1);
expect(callback).toHaveBeenCalledWith('latest');
} finally {
jest.restoreAllMocks();
}
});
});
3 changes: 2 additions & 1 deletion packages/vtable/src/tools/debounce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,14 @@ export function debounce(func: Function, wait?: number, options?: any) {
return result;
}

// 计算尾调用前的剩余等待时间,避免连续调用时反复创建零延迟定时器。
function remainingWait(time: number) {
// 计算 time 与最近一次调用 debounced 函数的时间差
const timeSinceLastCall = time - lastCallTime;
// 计算 time 与最近一次调用 func 函数的时间差
const timeSinceLastInvoke = time - lastInvokeTime;
// 用 wait 减去已经等待的时间
const timeWaiting = wait && -timeSinceLastCall;
const timeWaiting = (wait as number) - timeSinceLastCall;

return maxing ? Math.min(timeWaiting as number, maxWait - timeSinceLastInvoke) : timeWaiting;
}
Expand Down
Loading