You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

пре 3 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import { useMemo, useRef } from 'react';
  2. import useMounted from './useMounted';
  3. import useWillUnmount from './useWillUnmount';
  4. /*
  5. * Browsers including Internet Explorer, Chrome, Safari, and Firefox store the
  6. * delay as a 32-bit signed integer internally. This causes an integer overflow
  7. * when using delays larger than 2,147,483,647 ms (about 24.8 days),
  8. * resulting in the timeout being executed immediately.
  9. *
  10. * via: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout
  11. */
  12. var MAX_DELAY_MS = Math.pow(2, 31) - 1;
  13. function setChainedTimeout(handleRef, fn, timeoutAtMs) {
  14. var delayMs = timeoutAtMs - Date.now();
  15. handleRef.current = delayMs <= MAX_DELAY_MS ? setTimeout(fn, delayMs) : setTimeout(function () {
  16. return setChainedTimeout(handleRef, fn, timeoutAtMs);
  17. }, MAX_DELAY_MS);
  18. }
  19. /**
  20. * Returns a controller object for setting a timeout that is properly cleaned up
  21. * once the component unmounts. New timeouts cancel and replace existing ones.
  22. */
  23. export default function useTimeout() {
  24. var isMounted = useMounted(); // types are confused between node and web here IDK
  25. var handleRef = useRef();
  26. useWillUnmount(function () {
  27. return clearTimeout(handleRef.current);
  28. });
  29. return useMemo(function () {
  30. var clear = function clear() {
  31. return clearTimeout(handleRef.current);
  32. };
  33. function set(fn, delayMs) {
  34. if (delayMs === void 0) {
  35. delayMs = 0;
  36. }
  37. if (!isMounted()) return;
  38. clear();
  39. if (delayMs <= MAX_DELAY_MS) {
  40. // For simplicity, if the timeout is short, just set a normal timeout.
  41. handleRef.current = setTimeout(fn, delayMs);
  42. } else {
  43. setChainedTimeout(handleRef, fn, Date.now() + delayMs);
  44. }
  45. }
  46. return {
  47. set: set,
  48. clear: clear
  49. };
  50. }, []);
  51. }