163 lines
5.1 KiB
JavaScript
163 lines
5.1 KiB
JavaScript
"use strict";
|
||
// timer-manager.ts
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
exports.getTimerStats = exports.clearAllTimers = exports.unhookTimers = exports.hookTimers = exports.timerManager = void 0;
|
||
class GlobalTimerManager {
|
||
timers = new Map();
|
||
isHooked = false;
|
||
// 保存原始函数
|
||
original = {
|
||
setTimeout: global.setTimeout,
|
||
setInterval: global.setInterval,
|
||
setImmediate: global.setImmediate, clearTimeout: global.clearTimeout,
|
||
clearInterval: global.clearInterval,
|
||
clearImmediate: global.clearImmediate,
|
||
};
|
||
/**
|
||
* 开始拦截全局定时器
|
||
*/
|
||
hook() {
|
||
if (this.isHooked) {
|
||
console.warn('[TimerManager] Already hooked');
|
||
return;
|
||
}
|
||
const self = this;
|
||
// Hook setTimeout
|
||
global.setTimeout = function (callback, ms, ...args) {
|
||
const id = self.original.setTimeout((...callbackArgs) => {
|
||
self.timers.delete(id); // 执行完后移除
|
||
callback(...callbackArgs);
|
||
}, ms, ...args);
|
||
self.timers.set(id, {
|
||
id,
|
||
type: 'timeout',
|
||
createdAt: Date.now(),
|
||
});
|
||
return id;
|
||
};
|
||
// Hook setInterval
|
||
global.setInterval = function (callback, ms, ...args) {
|
||
const id = self.original.setInterval(callback, ms, ...args);
|
||
self.timers.set(id, {
|
||
id,
|
||
type: 'interval',
|
||
createdAt: Date.now(),
|
||
});
|
||
return id;
|
||
};
|
||
// Hook setImmediate
|
||
global.setImmediate = function (callback, ...args) {
|
||
const id = self.original.setImmediate((...callbackArgs) => {
|
||
self.timers.delete(id); // 执行完后移除
|
||
callback(...callbackArgs);
|
||
}, ...args);
|
||
self.timers.set(id, {
|
||
id,
|
||
type: 'immediate',
|
||
createdAt: Date.now(),
|
||
});
|
||
return id;
|
||
};
|
||
// Hook clear方法(确保从追踪中移除)
|
||
global.clearTimeout = ((id) => {
|
||
self.timers.delete(id);
|
||
return self.original.clearTimeout(id);
|
||
});
|
||
global.clearInterval = ((id) => {
|
||
self.timers.delete(id);
|
||
return self.original.clearInterval(id);
|
||
});
|
||
global.clearImmediate = ((id) => {
|
||
self.timers.delete(id);
|
||
return self.original.clearImmediate(id);
|
||
});
|
||
this.isHooked = true;
|
||
console.log('[TimerManager] Hooked global timer functions');
|
||
}
|
||
/**
|
||
* 恢复原始的全局定时器函数
|
||
*/
|
||
unhook() {
|
||
if (!this.isHooked) {
|
||
return;
|
||
}
|
||
global.setTimeout = this.original.setTimeout;
|
||
global.setInterval = this.original.setInterval;
|
||
global.setImmediate = this.original.setImmediate;
|
||
global.clearTimeout = this.original.clearTimeout;
|
||
global.clearInterval = this.original.clearInterval;
|
||
global.clearImmediate = this.original.clearImmediate;
|
||
this.isHooked = false;
|
||
}
|
||
/**
|
||
* 清除所有被追踪的定时器
|
||
*/
|
||
clearAll() {
|
||
const count = this.timers.size;
|
||
this.timers.forEach((record) => {
|
||
if (record.type === 'immediate') {
|
||
this.original.clearImmediate.call(null, record.id);
|
||
}
|
||
else {
|
||
this.original.clearTimeout.call(null, record.id);
|
||
}
|
||
});
|
||
this.timers.clear();
|
||
return count;
|
||
}
|
||
/**
|
||
* 按类型清除定时器
|
||
*/
|
||
clearByType(type) {
|
||
let count = 0;
|
||
this.timers.forEach((record, id) => {
|
||
if (record.type === type) {
|
||
if (type === 'immediate') {
|
||
this.original.clearImmediate.call(null, id);
|
||
}
|
||
else {
|
||
this.original.clearTimeout.call(null, id);
|
||
}
|
||
this.timers.delete(id);
|
||
count++;
|
||
}
|
||
});
|
||
return count;
|
||
}
|
||
/**
|
||
* 获取当前活跃的定时器数量
|
||
*/
|
||
getActiveCount() {
|
||
return this.timers.size;
|
||
}
|
||
/**
|
||
* 获取定时器统计信息
|
||
*/
|
||
getStats() {
|
||
const stats = {
|
||
timeout: 0,
|
||
interval: 0,
|
||
immediate: 0,
|
||
};
|
||
this.timers.forEach((record) => {
|
||
stats[record.type]++;
|
||
});
|
||
return stats;
|
||
}
|
||
/**
|
||
* 获取所有定时器的详细信息(用于调试)
|
||
*/
|
||
getTimers() {
|
||
return Array.from(this.timers.values());
|
||
}
|
||
}
|
||
exports.timerManager = new GlobalTimerManager();
|
||
const hookTimers = () => exports.timerManager.hook();
|
||
exports.hookTimers = hookTimers;
|
||
const unhookTimers = () => exports.timerManager.unhook();
|
||
exports.unhookTimers = unhookTimers;
|
||
const clearAllTimers = () => exports.timerManager.clearAll();
|
||
exports.clearAllTimers = clearAllTimers;
|
||
const getTimerStats = () => exports.timerManager.getStats();
|
||
exports.getTimerStats = getTimerStats;
|