Maison > interface Web > js tutoriel > Minuterie - Défis JavaScript

Minuterie - Défis JavaScript

Mary-Kate Olsen
Libérer: 2024-11-04 12:44:02
original
1018 Les gens l'ont consulté

Timer - JavaScript Challenges

Vous pouvez trouver tout le code dans cet article sur le dépôt Github.


Défis liés à la minuterie de programmation asynchrone


Cache avec limite de temps

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);
Copier après la connexion

Annuler l'intervalle

/**
 * @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.
Copier après la connexion

Annuler le délai d'attente

/**
 * @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.
Copier après la connexion

Effacer tous les délais d'attente

/**
 * 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.
Copier après la connexion

Anti-rebond

/**
 * @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 .
Copier après la connexion

Étrangler

/**
 * @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
Copier après la connexion

Répéter l'intervalle

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 < count) {
      callbackFn();
      currentCount += 1;
    } else {
      clearInterval(timerId);
    }
  }, delay);

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

// Usage example
const cancel = repeat(() => fetchData(URL), 2000, 5);
setTimeout(() => {
  cancel.clear();
}, 11000);
Copier après la connexion

Intervalle de reprise

/**
 * @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.
Copier après la connexion

Implémenter setInterval()

/**
 * @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);
Copier après la connexion

Implémenter setTimeout()

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);
Copier après la connexion

Référence

  • Fenêtre : méthode setTimeout() - MDN
  • Fenêtre : méthode setInterval() - MDN
  • Fenêtre : méthode clearInterval() - MDN
  • Fenêtre : méthode clearTimeout() - MDN
  • 2715. Annulation du délai d'attente - LeetCode
  • 2725. Annulation d'intervalle - LeetCode
  • 2622. Cache avec limite de temps - LeetCode
  • 2627. Anti-rebond - LeetCode
  • 2676. Accélérateur - LeetCode
  • Limitation de débit - Wikipedia.org
  • 28. implémenter clearAllTimeout() - BFE.dev
  • 4. implémenter l'accélérateur de base() - BFE.dev
  • 5. implémentez throttle() avec l'option de début et de fin - BFE.dev
  • 6. implémenter le debounce() de base - BFE.dev
  • 7. implémentez debounce() avec l'option de début et de fin - BFE.dev
  • JavaScript Asynchrone : exercices, pratiques, solutions - w3resource
  • GreatFrontEnd

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal