”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > JavaScript挑战:Timer计时器实现攻略

JavaScript挑战:Timer计时器实现攻略

发布于2025-04-12
浏览:698

Timer - JavaScript Challenges您可以在repo github的这篇文章中找到所有代码。

异步编程计时器相关的挑战


与时间限制的缓存


类TimeLimitedCache { constructor(){ this._cache = new Map(); } set(键,值,持续时间){ const找到= this._cache.has(key); 如果(找到){ clearTimeOut(this._cache.get(key).ref); } this._cache.set(key,{ 价值, 参考:settimeout(()=> { this._cache.delete(key); }, 期间), }); 发现返回; } 获取(键){ if(this._cache.has(key)){ 返回this._cache.get(key); } 别的 { 返回-1; } } 数数() { 返回this._cache.size; } } //用法示例 const timeLimitedCache = new TimeLimitedCache(); console.log(timeLimitedCache.set(1,'first',1000)); // => false console.log(timeLimitedCache.get(1).value); // =>'第一个' console.log(timeLimitedCache.Count()); // => 1 settimeout(()=> { console.log(timeLimitedCache.Count()); // => 0 console.log(timeLimitedCache.get(1)); // => -1 },2000);

class TimeLimitedCache {
  constructor() {
    this._cache = new Map();
  }

  set(key, value, duration) {
    const found = this._cache.has(key);

    if (found) {
      clearTimeout(this._cache.get(key).ref);
    }

    this._cache.set(key, {
      value,
      ref: setTimeout(() => {
        this._cache.delete(key);
      }, duration),
    });

    return found;
  }

  get(key) {
    if (this._cache.has(key)) {
      return this._cache.get(key);
    } else {
      return -1;
    }
  }

  count() {
    return this._cache.size;
  }
}

// Usage example
const timeLimitedCache = new TimeLimitedCache();
console.log(timeLimitedCache.set(1, 'first', 1000)); // => false
console.log(timeLimitedCache.get(1).value); // => 'first'
console.log(timeLimitedCache.count()); // => 1 
setTimeout(() => {
  console.log(timeLimitedCache.count()); // => 0
  console.log(timeLimitedCache.get(1)); // => -1
}, 2000);

/** * @param {function}回调 * @param {number}延迟 * @param {...任何} args * @returns {function} */ 函数setCancellable Interval(callbackfn,delay,... args){ const timerId = setInterval(callbackfn,delay,... args); 返回()=> { clear Interval(TimerId); }; } //用法示例 令i = 0; // t = 0: const cancel = setCancellableInterval((()=> { 我 ; },100); // t = 50: 取消(); // t = 100:我仍然是0,因为cancel()被调用。

/**
 * @param {Function} callback
 * @param {number} delay
 * @param {...any} args
 * @returns {Function}
 */
function setCancellableInterval(callbackFn, delay, ...args) {
  const timerId = setInterval(callbackFn, delay, ...args);

  return () => {
    clearInterval(timerId);
  };
}

// Usage example
let i = 0;
// t = 0:
const cancel = setCancellableInterval(() => {
  i  ;
}, 100);
// t = 50:
cancel();
// t = 100: i is still 0 because cancel() was called.

/** * @param {function} callbackfn * @param {number}延迟 * @param {...任何} args * @returns {function} */ 函数setCancellabletimeout(callbackfn,delay,... args){ const TimerId = settimeout(callbackfn,delay,... args); 返回()=> { cleartimeout(timerid); }; } //用法示例 令i = 0; // t = 0: const cancel = setCancellabletimeout(()=> { 我 ; },100); // t = 50: 取消(); // t = 100:我仍然是0,因为cancel()被调用。

/**
 * @param {Function} callbackFn
 * @param {number} delay
 * @param {...any} args
 * @returns {Function}
 */
function setCancellableTimeout(callbackFn, delay, ...args) {
  const timerId = setTimeout(callbackFn, delay, ...args);

  return () => {
    clearTimeout(timerId);
  };
}

// Usage example
let i = 0;
// t = 0:
const cancel = setCancellableTimeout(() => {
  i  ;
}, 100);
// t = 50:
cancel();
// t = 100: i is still 0 because cancel() was called.

/** *从window.settimeout取消所有计时器 */ const timerqueue = []; const OriginalSetTimeOut = window.setTimeOut; window.setTimeout = function(callbackfn,delay,... args){ const timerId = ointersetTimeout(callbackfn,delay,... args); timerqueue.push(timerid); 返回timerid; } 功能ClearallTimeOut(){ while(timerqueue.length){ clearTimeout(timerqueue.pop()); } } //用法示例 settimeout(func1,10000) settimeout(func2,10000) settimeout(func3,10000) //所有3个功能在10秒后安排 clearallTimeOut() //取消所有计划的任务。

/**
 * cancel all timer from window.setTimeout
 */

const timerQueue = [];

const originalSetTimeout = window.setTimeout;

window.setTimeout = function (callbackFn, delay, ...args) {
  const timerId = originalSetTimeout(callbackFn, delay, ...args);
  timerQueue.push(timerId);

  return timerId;
}


function clearAllTimeout() {
  while (timerQueue.length) {
    clearTimeout(timerQueue.pop());
  }
}


// Usage example
setTimeout(func1, 10000)
setTimeout(func2, 10000)
setTimeout(func3, 10000)
// all 3 functions are scheduled 10 seconds later
clearAllTimeout()
// all scheduled tasks are cancelled.

/** * @param {function} fn * @param {number}等待 * @return {function} */ 函数debounce(fn,wait = 0){ 令timerid = null; 返回功能(... args){ const context = this; cleartimeout(timerid); timerId = settimeout(()=> { timerid = null; fn.call(上下文,... args); }, 等待); } } //用法示例 令i = 0; 功能递增(){ i = 1; } const debouncedIncrement = debounce(增量,100); // t = 0:调用debouncedIncrement()。 debouncedIncrement(); // i = 0 // t = 50:我仍然是0,因为100ms尚未通过。 //再次致电debouncedIncrement()。 debouncedIncrement(); // i = 0 // t = 100:我还是0,因为它只有 //自上次debouncedincrement()t = 50以来为50ms。 // t = 150:因为从那以后通过了100ms // t = 50的最后一个debouncedincrement(), //递增被调用,我现在是1。

/**
 * @param {Function} fn 
 * @param {number} wait 
 * @return {Function}
 */

function debounce(fn, wait = 0) {
  let timerId = null;

  return function (...args) {
    const context = this;
    clearTimeout(timerId);

    timerId = setTimeout(() => {
      timerId = null;
      fn.call(context, ...args);
    }, wait);
  }
}


// Usage example
let i = 0;
function increment() {
  i  = 1;
}
const debouncedIncrement = debounce(increment, 100);

// t = 0: Call debouncedIncrement().
debouncedIncrement(); // i = 0

// t = 50: i is still 0 because 100ms have not passed.
//  Call debouncedIncrement() again.
debouncedIncrement(); // i = 0

// t = 100: i is still 0 because it has only
//  been 50ms since the last debouncedIncrement() at t = 50.

// t = 150: Because 100ms have passed since
//  the last debouncedIncrement() at t = 50,
//  increment was invoked and i is now 1 .

/** * @param {function} fn * @param {number}等待 * @return {function} */ 功能节气门(fn,wait = 0){ 让应该throttle = false; 返回功能(... args){ if(应该){ 返回; } 应该throttle = true; settimeout(()=> { 应该throttle = false; }, 等待); fn.call(this,... args); } } //用法示例 令i = 0; 功能递增(){ 我 ; } const throttledIncrement =油门(增量,100); // t = 0:调用thtottledincrement()。我现在是1。 油门固定(); // i = 1 // t = 50:再次调用thtottledincrement()。 //我仍然是1,因为100ms尚未通过。 油门固定(); // i = 1 // t = 101:再次调用thtottledincrement()。我现在2。 //我可以增加,因为它已经超过100ms //自从上次漏油increment()调用t = 0。 油门固定(); // i = 2

/**
 * @param {Function} fn 
 * @param {number} wait 
 * @return {Function}
 */

function throttle(fn, wait = 0) {
  let shouldThrottle = false;

  return function (...args) {
    if (shouldThrottle) {
      return;
    }

    shouldThrottle = true;
    setTimeout(() => {
      shouldThrottle = false;
    }, wait);

    fn.call(this, ...args);
  }
}

// Usage example
let i = 0;
function increment() {
  i  ;
}
const throttledIncrement = throttle(increment, 100);

// t = 0: Call throttledIncrement(). i is now 1.
throttledIncrement(); // i = 1

// t = 50: Call throttledIncrement() again.
//  i is still 1 because 100ms have not passed.
throttledIncrement(); // i = 1

// t = 101: Call throttledIncrement() again. i is now 2.
//  i can be incremented because it has been more than 100ms
//  since the last throttledIncrement() call at t = 0.
throttledIncrement(); // i = 2

功能fetchdata(url){ 返回获取(URL) 。然后((响应)=> { if(!wendesp.ok){ 提出新的错误(`错误:$ {wendesp.status}`); } 返回响应blob(); })) 。然后((data)=> { console.log(data); })) .catch(((err)=> { console.log(`错误:$ {err}`); }); } 函数重复(callbackfn,延迟,计数){ 令CurrentCount = 0; const TimerId = setInterval(()=> { if(currentCount clear Interval(timerId), } } //用法示例 const取消=重复(()=> fetchdata(url),2000,5); settimeout(()=> { cancel.clear(); },11000);

const URL = 'https://fastly.picsum.photos/id/0/5000/3333.jpg?hmac=_j6ghY5fCfSD6tvtcV74zXivkJSPIfR9B8w34XeQmvU';

function fetchData(url) {
  return fetch(url)
    .then((response) => {
      if (!response.ok) {
        throw new Error(`Error: ${response.status}`);
      }

      return response.blob();
    })
    .then((data) => {
      console.log(data);
    })
    .catch((err) => {
      console.log(`Error: ${err}`);
    });
}

function repeat(callbackFn, delay, count) {
  let currentCount = 0;

  const timerId = setInterval(() => {
    if (currentCount  clearInterval(timerId),
  }
}

// Usage example
const cancel = repeat(() => fetchData(URL), 2000, 5);
setTimeout(() => {
  cancel.clear();
}, 11000);

/** * @param {function} callbackfn * @param {number}延迟 * @param {...任何} args * @returns {{start:function,puse:function,stop:function}}} */ 功能createresumable Interval(callbackfn,delay,... args){ 令timerid = null; 让停止= false; 功能clearTimer(){ clear Interval(TimerId); timerid = null; } 函数start(){ 如果(停止|| TimerId){ 返回; } callbackfn(... args); timerId = setInterval(callbackfn,delay,... args); } 功能暂停(){ 如果(停止){ 返回; } cleartimer(); } 函数stop(){ 停止= true; cleartimer(); } 返回 { 开始, 暂停, 停止, }; } //用法示例 令i = 0; // t = 0: const Interval = Createresumable Interval(()=> { 我 ; },10); // t = 10: Interval.start(); //我现在是1。 // t = 20:回调执行,我现在是2。 // t = 25: Interval.pause(); // t = 30:我一直保持2个,因为intervel.pape()被调用。 // t = 35: Interval.start(); //我现在是3。 // t = 45:回调执行,我现在是4。 // t = 50: Interval.stop(); //我留在4岁。

/**
 * @param {Function} callbackFn
 * @param {number} delay
 * @param {...any} args
 * @returns {{start: Function, pause: Function, stop: Function}}
 */

function createResumableInterval(callbackFn, delay, ...args) {
  let timerId = null;
  let stopped = false;

  function clearTimer() {
    clearInterval(timerId);
    timerId = null;
  }

  function start() {
    if (stopped || timerId) {
      return;
    }

    callbackFn(...args);
    timerId = setInterval(callbackFn, delay, ...args);
  }

  function pause() {
    if (stopped) {
      return;
    }

    clearTimer();
  }

  function stop() {
    stopped = true;
    clearTimer();
  }

  return {
    start,
    pause,
    stop,
  };
}

// Usage example
let i = 0;
// t = 0:
const interval = createResumableInterval(() => {
  i  ;
}, 10);
// t = 10:
interval.start(); // i is now 1.
// t = 20: callback executes and i is now 2.
// t = 25:
interval.pause();
// t = 30: i remains at 2 because interval.pause() was called.
// t = 35:
interval.start(); // i is now 3.
// t = 45: callback executes and i is now 4.
// t = 50:
interval.stop(); // i remains at 4.

/** * @param {function} callbackfn * @param {number}延迟 * @return {object} */ //使用`requestAnimationFrame' 功能mysetInterval(callbackfn,delay){ 令timerid = null; 让开始= date.now(); // 环形 功能循环(){ const current = date.now(); if(当前 - 开始> =延迟){ callbackfn(); 开始=电流; } timerId = requestAnimationFrame(loop); } //运行循环 环形(); 返回 { clear :()=> cancelAnimationFrame(TimerId), } } const Intertal = mySetInterval(()=> { console.log('Interval Tick'); },1000); // 取消 settimeout(()=> { Interval.Clear(); },5000); //使用`settimeout' 功能mysetInterval(callbackfn,delay){ 令timerid = null; 让开始= date.now(); 让计数= 0; // 环形 功能循环(){ const draft = date.now() - start -count * delay; 计数= 1; timerId = settimeout(()=> { callbackfn(); 环形(); },延迟 - 漂移); } //运行循环 环形(); 返回 { clear :()=> cleartimeout(timerId), } } const Intertal = mySetInterval(()=> { console.log('Interval Tick'); },1000); // 取消 settimeout(()=> { Interval.Clear(); },5000);

/**
 * @param {Function} callbackFn
 * @param {number} delay
 * @return {object}
 */

// use `requestAnimationFrame`
function mySetInterval(callbackFn, delay) {
  let timerId = null;
  let start = Date.now();

  // loop
  function loop() {
    const current = Date.now();

    if (current - start >= delay) {
      callbackFn();
      start = current;
    }

    timerId = requestAnimationFrame(loop);
  }

  // run loop
  loop();

  return {
    clear: () => cancelAnimationFrame(timerId),
  }
}


const interval = mySetInterval(() => {
  console.log('Interval tick');
}, 1000);

// cancel
setTimeout(() => {
  interval.clear();
}, 5000);



// use `setTimeout`
function mySetInterval(callbackFn, delay) {
  let timerId = null;
  let start = Date.now();
  let count = 0;

  // loop
  function loop() {
    const drift = Date.now() - start - count * delay;
    count  = 1;

    timerId = setTimeout(() => {
      callbackFn();
      loop();
    }, delay - drift);
  }

  // run loop
  loop();

  return {
    clear: () => clearTimeout(timerId),
  }
}

const interval = mySetInterval(() => {
  console.log('Interval tick');
}, 1000);

// cancel
setTimeout(() => {
  interval.clear();
}, 5000);
[2 令ElapsedTime = 0; const间隔= 100; const interceTalid = setInterval(()=> { ELAPSEDTIME = Interval; if(ElapsedTime> = delay){ clear Interval(Intervalid); callbackfn(); } }, 间隔); } //用法示例 mySetTimeout(()=> { console.log(“此消息将在2秒后显示。”); },2000);

参考
function setTimeout(callbackFn, delay) {
  let elapsedTime = 0;
  const interval = 100;

  const intervalId = setInterval(() => {
    elapsedTime  = interval;

    if (elapsedTime >= delay) {
      clearInterval(intervalId);
      callbackFn();
    }
  }, interval);
}

// Usage example
mySetTimeout(() => {
  console.log('This message is displayed after 2 seconds.');
}, 2000);

窗口:setInterval()方法-MDN

    窗口:clearInterval()方法-MDN
  • 窗口:cleartimeout()method -mdn
  • 2715。超时取消 - leetcode
  • 2725。间隔取消 - leetcode
  • 2622。带有时间限制的缓存-LeetCode
  • 2627。 debounce -leetcode
  • 2676。油门-LeetCode
  • 28。实现clearallTimeOut()-bfe.dev
  • 4。实现基本油门()-bfe.dev
  • 5。带有领先和尾随选项的实现throttle()-BFE.Dev
  • 6。实施基本debounce()-BFE.DEV
  • 7。用领先和尾随的选项-BFE.DEV
  • JavaScript异步:练习,练习,解决方案-W3Resource
  • Greatfrontend
版本声明 本文转载于:https://dev.to/mitchell_cheng/timer-javascript-challenges-25l7?1如有侵犯,请联系[email protected]删除
最新教程 更多>

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3