@cloudcome/utils-core
Version:
cloudcome core utils
1 lines • 6.63 kB
Source Map (JSON)
{"version":3,"file":"timer.cjs","sources":["../src/timer.ts"],"sourcesContent":["/**\n * 定时器状态接口\n */\nexport type TimerState = {\n /**\n * 执行次数\n */\n times: number;\n /**\n * 开始时间戳\n */\n startAt: number;\n /**\n * 停止时间戳\n */\n stopAt: number;\n /**\n * 暂停时间戳\n */\n pauseAt: number;\n /**\n * 恢复时间戳\n */\n resumeAt: number;\n /**\n * 当前时间戳\n */\n currentAt: number;\n /**\n * 总耗时(包括暂停时间)\n */\n elapsedTime: number;\n /**\n * 实际运行时间(不包括暂停时间)\n */\n runningTime: number;\n /**\n * 当前间隔时间\n */\n intervalTime: number;\n};\n\nexport type TimerHandler = {\n /**\n * 开始\n */\n start: () => void;\n /**\n * 暂停\n */\n pause: () => void;\n /**\n * 恢复\n */\n resume: (immediate?: boolean) => void;\n /**\n * 停止\n */\n stop: () => void;\n};\n\nconst STATUS_READY = 0;\nconst STATUS_START = 1;\nconst STATUS_PAUSE = 2;\nconst STATUS_STOP = 3;\n\n/**\n * 创建间隔定时器核心函数\n *\n * @param nextTime - 用于安排下一次执行的函数\n * @param effect - 每次执行的回调函数,接收定时器状态和可选的next函数\n * @returns 返回包含控制方法的对象\n */\nexport function makeInterval(\n nextTime: (call: () => void) => void,\n effect: (timer: TimerState, next?: () => void) => unknown,\n) {\n let startAt = 0;\n let lastAt = 0;\n let stopAt = 0;\n let pauseAt = 0;\n let resumeAt = 0;\n let times = 0;\n let status = STATUS_READY;\n let runningTime = 0;\n\n const execute = () => {\n if (status >= STATUS_PAUSE) return;\n\n const now = Date.now();\n const intervalTime = lastAt > 0 ? now - lastAt : 0;\n runningTime += intervalTime;\n lastAt = now;\n const state: TimerState = {\n times: ++times,\n startAt,\n stopAt,\n pauseAt,\n resumeAt,\n currentAt: now,\n elapsedTime: startAt > 0 ? now - startAt : 0,\n runningTime,\n intervalTime,\n };\n\n if (effect.length === 2) {\n effect(state, () => {\n nextTime(execute);\n });\n } else {\n effect(state);\n nextTime(execute);\n }\n };\n\n const canStart = () => status === STATUS_READY;\n const start = () => {\n if (!canStart()) return;\n status = STATUS_START;\n startAt = Date.now();\n execute();\n };\n\n const canStop = () => status === STATUS_START;\n const stop = () => {\n if (!canStop()) return;\n status = STATUS_STOP;\n stopAt = Date.now();\n };\n\n const canPause = () => status === STATUS_START;\n const pause = () => {\n if (!canPause()) return;\n status = STATUS_PAUSE;\n pauseAt = Date.now();\n };\n\n const canResume = () => status === STATUS_PAUSE;\n const resume = () => {\n if (!canResume()) return;\n status = STATUS_START;\n resumeAt = Date.now();\n lastAt = resumeAt;\n execute();\n };\n\n return {\n canStart,\n canStop,\n canPause,\n canResume,\n start,\n stop,\n pause,\n resume,\n execute,\n };\n}\n\nexport type TimerOptions = {\n /**\n * 是否在定时器开始时立即执行回调\n */\n leading?: boolean;\n /**\n * 是否在定时器停止时执行最后一次回调\n */\n trailing?: boolean;\n};\n\n/**\n * 创建一个基于 `setTimeout` 的间隔定时器\n *\n * @param callback - 每次间隔执行的回调函数,接收定时器状态和可选的 `next` 函数\n * @param interval - 间隔时间,单位为毫秒\n * @param options - 配置选项\n * @returns {TimerHandler}\n */\nexport function timeInterval(\n callback: (state: TimerState, next?: () => void) => unknown,\n interval: number,\n options?: TimerOptions,\n): TimerHandler {\n let timeId: number | NodeJS.Timeout;\n const { canStart, canStop, canPause, canResume, start, stop, pause, resume, execute } = makeInterval((call) => {\n timeId = setTimeout(call, interval);\n }, callback);\n\n return {\n start() {\n if (!canStart()) return;\n\n if (options?.leading) {\n start();\n } else {\n timeId = setTimeout(start, interval);\n }\n },\n\n stop() {\n if (!canStop()) return;\n if (options?.trailing) execute();\n\n clearTimeout(timeId);\n stop();\n },\n\n pause() {\n if (!canPause()) return;\n if (options?.trailing) execute();\n\n clearTimeout(timeId);\n pause();\n },\n\n resume(immediate?: boolean) {\n if (!canResume()) return;\n\n if (immediate || options?.leading) {\n resume();\n } else {\n timeId = setTimeout(resume, interval);\n }\n },\n };\n}\n"],"names":[],"mappings":";;AA6DA,MAAM,eAAe;AACrB,MAAM,eAAe;AACrB,MAAM,eAAe;AACrB,MAAM,cAAc;AASJ,SAAA,aACd,UACA,QACA;AACA,MAAI,UAAU;AACd,MAAI,SAAS;AACb,MAAI,SAAS;AACb,MAAI,UAAU;AACd,MAAI,WAAW;AACf,MAAI,QAAQ;AACZ,MAAI,SAAS;AACb,MAAI,cAAc;AAElB,QAAM,UAAU,MAAM;AACpB,QAAI,UAAU,aAAc;AAEtB,UAAA,MAAM,KAAK,IAAI;AACrB,UAAM,eAAe,SAAS,IAAI,MAAM,SAAS;AAClC,mBAAA;AACN,aAAA;AACT,UAAM,QAAoB;AAAA,MACxB,OAAO,EAAE;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,aAAa,UAAU,IAAI,MAAM,UAAU;AAAA,MAC3C;AAAA,MACA;AAAA,IACF;AAEI,QAAA,OAAO,WAAW,GAAG;AACvB,aAAO,OAAO,MAAM;AAClB,iBAAS,OAAO;AAAA,MAAA,CACjB;AAAA,IAAA,OACI;AACL,aAAO,KAAK;AACZ,eAAS,OAAO;AAAA,IAAA;AAAA,EAEpB;AAEM,QAAA,WAAW,MAAM,WAAW;AAClC,QAAM,QAAQ,MAAM;AACd,QAAA,CAAC,WAAY;AACR,aAAA;AACT,cAAU,KAAK,IAAI;AACX,YAAA;AAAA,EACV;AAEM,QAAA,UAAU,MAAM,WAAW;AACjC,QAAM,OAAO,MAAM;AACb,QAAA,CAAC,UAAW;AACP,aAAA;AACT,aAAS,KAAK,IAAI;AAAA,EACpB;AAEM,QAAA,WAAW,MAAM,WAAW;AAClC,QAAM,QAAQ,MAAM;AACd,QAAA,CAAC,WAAY;AACR,aAAA;AACT,cAAU,KAAK,IAAI;AAAA,EACrB;AAEM,QAAA,YAAY,MAAM,WAAW;AACnC,QAAM,SAAS,MAAM;AACf,QAAA,CAAC,YAAa;AACT,aAAA;AACT,eAAW,KAAK,IAAI;AACX,aAAA;AACD,YAAA;AAAA,EACV;AAEO,SAAA;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAqBgB,SAAA,aACd,UACA,UACA,SACc;AACV,MAAA;AACJ,QAAM,EAAE,UAAU,SAAS,UAAU,WAAW,OAAO,MAAM,OAAO,QAAQ,QAAY,IAAA,aAAa,CAAC,SAAS;AACpG,aAAA,WAAW,MAAM,QAAQ;AAAA,KACjC,QAAQ;AAEJ,SAAA;AAAA,IACL,QAAQ;AACF,UAAA,CAAC,WAAY;AAEjB,UAAI,SAAS,SAAS;AACd,cAAA;AAAA,MAAA,OACD;AACI,iBAAA,WAAW,OAAO,QAAQ;AAAA,MAAA;AAAA,IAEvC;AAAA,IAEA,OAAO;AACD,UAAA,CAAC,UAAW;AACZ,UAAA,SAAS,SAAkB,SAAA;AAE/B,mBAAa,MAAM;AACd,WAAA;AAAA,IACP;AAAA,IAEA,QAAQ;AACF,UAAA,CAAC,WAAY;AACb,UAAA,SAAS,SAAkB,SAAA;AAE/B,mBAAa,MAAM;AACb,YAAA;AAAA,IACR;AAAA,IAEA,OAAO,WAAqB;AACtB,UAAA,CAAC,YAAa;AAEd,UAAA,aAAa,SAAS,SAAS;AAC1B,eAAA;AAAA,MAAA,OACF;AACI,iBAAA,WAAW,QAAQ,QAAQ;AAAA,MAAA;AAAA,IACtC;AAAA,EAEJ;AACF;;;"}