jsly 3.1.6 → 3.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -7687,5 +7687,134 @@ function highlightKeyword(text, keyword, config = {
7687
7687
  return text.replace(pattern, match => `<${tag} style="${style}">${match}</${tag}>`);
7688
7688
  }
7689
7689
 
7690
- export { $bus, buildObjFormData, camelToSnake, convertKeys, copyByClipboardAPI, copyByExecCommand, copyToClipboard, debounce, deepDiff, generateBrowserId, highlightKeyword, randomHash, sha256, shallowDiff, snakeToCamel, throttle, toggleConvertCase };
7690
+ /**
7691
+ * 基于 requestAnimationFrame 实现的定时器(RAF Interval)
7692
+ *
7693
+ * 功能类似于 setInterval,但内部使用 requestAnimationFrame 驱动。
7694
+ * 相比 setInterval:
7695
+ * - 与浏览器刷新率同步,更平滑
7696
+ * - 页面不可见时会自动暂停(节省性能)
7697
+ * - 不易出现掉帧或时间漂移问题
7698
+ *
7699
+ * 适用于动画、轮播、游戏循环等需要与渲染帧同步的场景。
7700
+ *
7701
+ * @template {(...args: any[]) => any} F
7702
+ * @param {F} callback - 每次间隔触发时执行的函数。
7703
+ * @param {number} delay - 执行间隔时间(毫秒)。
7704
+ * @returns {() => void} 返回一个停止函数,用于取消循环。
7705
+ *
7706
+ * @example
7707
+ * const stop = rafInterval(() => {
7708
+ * console.log('每秒执行一次')
7709
+ * }, 1000)
7710
+ *
7711
+ * // 停止
7712
+ * stop()
7713
+ *
7714
+ * @example
7715
+ * // 在 Vue 中使用
7716
+ * let stop
7717
+ * onMounted(() => {
7718
+ * stop = rafInterval(() => {
7719
+ * rotate.value += 1
7720
+ * }, 16)
7721
+ * })
7722
+ *
7723
+ * onUnmounted(() => {
7724
+ * stop()
7725
+ * })
7726
+ */
7727
+ function rafInterval(callback, delay) {
7728
+ if (typeof callback !== 'function') {
7729
+ throw new TypeError('rafInterval expected a function as the first argument');
7730
+ }
7731
+ let start = performance.now();
7732
+ let frameId = null;
7733
+ let stopped = false;
7734
+ function loop(now) {
7735
+ if (stopped) return;
7736
+ const delta = now - start;
7737
+ if (delta >= delay) {
7738
+ callback();
7739
+ // 使用 += 防止时间漂移
7740
+ start += delay;
7741
+ }
7742
+ frameId = requestAnimationFrame(loop);
7743
+ }
7744
+ frameId = requestAnimationFrame(loop);
7745
+ return function stop() {
7746
+ stopped = true;
7747
+ if (frameId) cancelAnimationFrame(frameId);
7748
+ };
7749
+ }
7750
+
7751
+ /**
7752
+ * 轮询函数(Polling)
7753
+ *
7754
+ * 按指定间隔重复执行异步任务,直到:
7755
+ * 1. 任务返回 truthy 值(成功)
7756
+ * 2. 超时
7757
+ * 3. 被手动停止
7758
+ *
7759
+ * 常用于:
7760
+ * - 接口状态查询
7761
+ * - 等待资源加载完成
7762
+ * - 检测条件成立
7763
+ *
7764
+ * @template T
7765
+ * @param {() => Promise<T> | T} task - 需要轮询执行的函数(支持同步或异步)。
7766
+ * @param {Object} [options]
7767
+ * @param {number} [options.interval=1000] - 每次轮询间隔时间(毫秒)。
7768
+ * @param {number} [options.timeout=0] - 超时时间(毫秒),0 表示不限制。
7769
+ * @returns {{ promise: Promise<T>, stop: () => void }}
7770
+ *
7771
+ * @example
7772
+ * const { promise, stop } = poll(
7773
+ * () => fetch('/api/status').then(r => r.json()),
7774
+ * { interval: 2000, timeout: 10000 }
7775
+ * )
7776
+ *
7777
+ * promise.then(res => console.log('成功:', res))
7778
+ */
7779
+ function poll(task, {
7780
+ interval = 1000,
7781
+ timeout = 0
7782
+ } = {}) {
7783
+ if (typeof task !== 'function') {
7784
+ throw new TypeError('poll expected a function as the first argument');
7785
+ }
7786
+ let stopped = false;
7787
+ let startTime = Date.now();
7788
+ let timer = null;
7789
+ const promise = new Promise((resolve, reject) => {
7790
+ async function execute() {
7791
+ if (stopped) return;
7792
+ try {
7793
+ const result = await task();
7794
+ if (result) {
7795
+ resolve(result);
7796
+ return;
7797
+ }
7798
+ if (timeout && Date.now() - startTime >= timeout) {
7799
+ reject(new Error('Polling timeout'));
7800
+ return;
7801
+ }
7802
+ timer = setTimeout(execute, interval);
7803
+ } catch (err) {
7804
+ reject(err);
7805
+ }
7806
+ }
7807
+ execute();
7808
+ });
7809
+ function stop() {
7810
+ stopped = true;
7811
+ if (timer) clearTimeout(timer);
7812
+ }
7813
+ return {
7814
+ promise,
7815
+ stop
7816
+ };
7817
+ }
7818
+
7819
+ export { $bus, buildObjFormData, camelToSnake, convertKeys, copyByClipboardAPI, copyByExecCommand, copyToClipboard, debounce, deepDiff, generateBrowserId, highlightKeyword, poll, rafInterval, randomHash, sha256, shallowDiff, snakeToCamel, throttle, toggleConvertCase };
7691
7820
  //# sourceMappingURL=index.esm.js.map