{"id":2263,"date":"2024-11-10T17:54:14","date_gmt":"2024-11-10T09:54:14","guid":{"rendered":"https:\/\/fwq.ai\/blog\/2263\/"},"modified":"2024-11-10T17:54:14","modified_gmt":"2024-11-10T09:54:14","slug":"%e8%ae%a1%e6%97%b6%e5%99%a8-javascript-%e6%8c%91%e6%88%98","status":"publish","type":"post","link":"https:\/\/fwq.ai\/blog\/2263\/","title":{"rendered":"\u8ba1\u65f6\u5668 &#8211; JavaScript \u6311\u6218"},"content":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/img.php.cn\/upload\/article\/001\/246\/273\/173070274914389.jpg\" class=\"aligncenter\" title=\"\u8ba1\u65f6\u5668 &#8211; JavaScript \u6311\u6218\u63d2\u56fe\" alt=\"\u8ba1\u65f6\u5668 &#8211; JavaScript \u6311\u6218\u63d2\u56fe\" \/><\/p>\n<p>\u60a8\u53ef\u4ee5\u5728 hub \u4ed3\u5e93\u4e2d\u627e\u5230\u8fd9\u7bc7\u6587\u7ae0\u4e2d\u7684\u6240\u6709\u4ee3\u7801\u3002<\/p>\n<hr>\n<h2> \u5f02\u6b65\u7f16\u7a0b\u5b9a\u65f6\u5668\u76f8\u5173\u7684\u6311\u6218 <\/h2>\n<hr>\n<h3> \u6709\u65f6\u95f4\u9650\u5236\u7684\u7f13\u5b58 <\/h3>\n<pre>class timelimitedcache {\n  constructor() {\n    this._cache = new map();\n  }\n\n  set(key, value, duration) {\n    const found = this._cache.has(key);\n\n    if (found) {\n      cleartimeout(this._cache.get(key).ref);\n    }\n\n    this._cache.set(key, {\n      value,\n      ref: settimeout(() =&gt; {\n        this._cache.delete(key);\n      }, duration),\n    });\n\n    return found;\n  }\n\n  get(key) {\n    if (this._cache.has(key)) {\n      return this._cache.get(key);\n    } else {\n      return -1;\n    }\n  }\n\n  count() {\n    return this._cache.size;\n  }\n}\n\n\/\/ usage example\nconst timelimitedcache = new timelimitedcache();\nconsole.log(timelimitedcache.set(1, 'first', 1000)); \/\/ =&gt; false\nconsole.log(timelimitedcache.get(1).value); \/\/ =&gt; 'first'\nconsole.log(timelimitedcache.count()); \/\/ =&gt; 1 \nsettimeout(() =&gt; {\n  console.log(timelimitedcache.count()); \/\/ =&gt; 0\n  console.log(timelimitedcache.get(1)); \/\/ =&gt; -1\n}, 2000);\n<\/pre>\n<p> \u767b\u5f55\u540e\u590d\u5236 <\/p>\n<hr>\n<h3> \u53d6\u6d88\u95f4\u9694 <\/h3>\n<pre>\/**\n * @param {function} callback\n * @param {number} delay\n * @param {...any} args\n * @returns {function}\n *\/\nfunction setcancellableinterval(callbackfn, delay, ...args) {\n  const timerid = setinterval(callbackfn, delay, ...args);\n\n  return () =&gt; {\n    clearinterval(timerid);\n  };\n}\n\n\/\/ usage example\nlet i = 0;\n\/\/ t = 0:\nconst cancel = setcancellableinterval(() =&gt; {\n  i++;\n}, 100);\n\/\/ t = 50:\ncancel();\n\/\/ t = 100: i is still 0 because cancel() was called.\n<\/pre>\n<p> \u767b\u5f55\u540e\u590d\u5236 <\/p>\n<hr>\n<h3> \u53d6\u6d88\u8d85\u65f6 <\/h3>\n<pre>\/**\n * @param {function} callbackfn\n * @param {number} delay\n * @param {...any} args\n * @returns {function}\n *\/\nfunction setcancellabletimeout(callbackfn, delay, ...args) {\n  const timerid = settimeout(callbackfn, delay, ...args);\n\n  return () =&gt; {\n    cleartimeout(timerid);\n  };\n}\n\n\/\/ usage example\nlet i = 0;\n\/\/ t = 0:\nconst cancel = setcancellabletimeout(() =&gt; {\n  i++;\n}, 100);\n\/\/ t = 50:\ncancel();\n\/\/ t = 100: i is still 0 because cancel() was called.\n<\/pre>\n<p> \u767b\u5f55\u540e\u590d\u5236 <\/p>\n<hr>\n<h3> \u6e05\u9664\u6240\u6709\u8d85\u65f6\u5b9a\u65f6\u5668 <\/h3>\n<pre>\/**\n * cancel all timer from window.settimeout\n *\/\n\nconst timerqueue = [];\n\nconst originalsettimeout = window.settimeout;\n\nwindow.settimeout = function (callbackfn, delay, ...args) {\n  const timerid = originalsettimeout(callbackfn, delay, ...args);\n  timerqueue.push(timerid);\n\n  return timerid;\n}\n\n\nfunction clearalltimeout() {\n  while (timerqueue.length) {\n    cleartimeout(timerqueue.pop());\n  }\n}\n\n\n\/\/ usage example\nsettimeout(func1, 10000)\nsettimeout(func2, 10000)\nsettimeout(func3, 10000)\n\/\/ all 3 functions are scheduled 10 seconds later\nclearalltimeout()\n\/\/ all scheduled tasks are cancelled.\n<\/pre>\n<p> \u767b\u5f55\u540e\u590d\u5236 <\/p>\n<hr>\n<h3> \u53bb\u6296\u52a8 <\/h3>\n<pre>\/**\n * @param {function} fn \n * @param {number} wait \n * @return {function}\n *\/\n\nfunction debounce(fn, wait = 0) {\n  let timerid = null;\n\n  return function (...args) {\n    const context = this;\n    cleartimeout(timerid);\n\n    timerid = settimeout(() =&gt; {\n      timerid = null;\n      fn.call(context, ...args);\n    }, wait);\n  }\n}\n\n\n\/\/ usage example\nlet i = 0;\nfunction increment() {\n  i += 1;\n}\nconst debouncedincrement = debounce(increment, 100);\n\n\/\/ t = 0: call debouncedincrement().\ndebouncedincrement(); \/\/ i = 0\n\n\/\/ t = 50: i is still 0 because 100ms have not passed.\n\/\/  call debouncedincrement() again.\ndebouncedincrement(); \/\/ i = 0\n\n\/\/ t = 100: i is still 0 because it has only\n\/\/  been 50ms since the last debouncedincrement() at t = 50.\n\n\/\/ t = 150: because 100ms have passed since\n\/\/  the last debouncedincrement() at t = 50,\n\/\/  increment was invoked and i is now 1 .\n<\/pre>\n<p> \u767b\u5f55\u540e\u590d\u5236 <\/p>\n<hr>\n<h3> \u98ce\u95e8 <\/h3>\n<pre>\/**\n * @param {function} fn \n * @param {number} wait \n * @return {function}\n *\/\n\nfunction throttle(fn, wait = 0) {\n  let shouldthrottle = false;\n\n  return function (...args) {\n    if (shouldthrottle) {\n      return;\n    }\n\n    shouldthrottle = true;\n    settimeout(() =&gt; {\n      shouldthrottle = false;\n    }, wait);\n\n    fn.call(this, ...args);\n  }\n}\n\n\/\/ usage example\nlet i = 0;\nfunction increment() {\n  i++;\n}\nconst throttledincrement = throttle(increment, 100);\n\n\/\/ t = 0: call throttledincrement(). i is now 1.\nthrottledincrement(); \/\/ i = 1\n\n\/\/ t = 50: call throttledincrement() again.\n\/\/  i is still 1 because 100ms have not passed.\nthrottledincrement(); \/\/ i = 1\n\n\/\/ t = 101: call throttledincrement() again. i is now 2.\n\/\/  i can be incremented because it has been more than 100ms\n\/\/  since the last throttledincrement() call at t = 0.\nthrottledincrement(); \/\/ i = 2\n<\/pre>\n<p> \u767b\u5f55\u540e\u590d\u5236 <\/p>\n<hr>\n<h3> \u91cd\u590d\u95f4\u9694 <\/h3>\n<pre>const url = 'https:\/\/fastly.picsum.photos\/id\/0\/5000\/3333.jpg?hmac=_j6ghy5fcfsd6tvtcv74zxivkjspifr9b8w34xeqmvu';\n\nfunction fetchdata(url) {\n  return fetch(url)\n    .then((response) =&gt; {\n      if (!response.ok) {\n        throw new error(`error: ${response.status}`);\n      }\n\n      return response.blob();\n    })\n    .then((data) =&gt; {\n      console.log(data);\n    })\n    .catch((err) =&gt; {\n      console.log(`error: ${err}`);\n    });\n}\n\nfunction repeat(callbackfn, delay, count) {\n  let currentcount = 0;\n\n  const timerid = setinterval(() =&gt; {\n    if (currentcount &lt; count) {\n      callbackfn();\n      currentcount += 1;\n    } else {\n      clearinterval(timerid);\n    }\n  }, delay);\n\n  return {\n    clear: () =&gt; clearinterval(timerid),\n  }\n}\n\n\/\/ usage example\nconst cancel = repeat(() =&gt; fetchdata(url), 2000, 5);\nsettimeout(() =&gt; {\n  cancel.clear();\n}, 11000);\n<\/pre>\n<p> \u767b\u5f55\u540e\u590d\u5236 <\/p>\n<hr>\n<h3> \u53ef\u6062\u590d\u95f4\u9694 <\/h3>\n<pre>\/**\n * @param {function} callbackfn\n * @param {number} delay\n * @param {...any} args\n * @returns {{start: function, pause: function, stop: function}}\n *\/\n\nfunction createresumableinterval(callbackfn, delay, ...args) {\n  let timerid = null;\n  let stopped = false;\n\n  function cleartimer() {\n    clearinterval(timerid);\n    timerid = null;\n  }\n\n  function start() {\n    if (stopped || timerid) {\n      return;\n    }\n\n    callbackfn(...args);\n    timerid = setinterval(callbackfn, delay, ...args);\n  }\n\n  function pause() {\n    if (stopped) {\n      return;\n    }\n\n    cleartimer();\n  }\n\n  function stop() {\n    stopped = true;\n    cleartimer();\n  }\n\n  return {\n    start,\n    pause,\n    stop,\n  };\n}\n\n\/\/ usage example\nlet i = 0;\n\/\/ t = 0:\nconst interval = createresumableinterval(() =&gt; {\n  i++;\n}, 10);\n\/\/ t = 10:\ninterval.start(); \/\/ i is now 1.\n\/\/ t = 20: callback executes and i is now 2.\n\/\/ t = 25:\ninterval.pause();\n\/\/ t = 30: i remains at 2 because interval.pause() was called.\n\/\/ t = 35:\ninterval.start(); \/\/ i is now 3.\n\/\/ t = 45: callback executes and i is now 4.\n\/\/ t = 50:\ninterval.stop(); \/\/ i remains at 4.\n<\/pre>\n<p> \u767b\u5f55\u540e\u590d\u5236 <\/p>\n<hr>\n<h3> \u5b9e\u73b0 setinterval() <\/h3>\n<pre>\/**\n * @param {function} callbackfn\n * @param {number} delay\n * @return {object}\n *\/\n\n\/\/ use `requestanimationframe`\nfunction mysetinterval(callbackfn, delay) {\n  let timerid = null;\n  let start = date.now();\n\n  \/\/ loop\n  function loop() {\n    const current = date.now();\n\n    if (current - start &gt;= delay) {\n      callbackfn();\n      start = current;\n    }\n\n    timerid = requestanimationframe(loop);\n  }\n\n  \/\/ run loop\n  loop();\n\n  return {\n    clear: () =&gt; cancelanimationframe(timerid),\n  }\n}\n\n\nconst interval = mysetinterval(() =&gt; {\n  console.log('interval tick');\n}, 1000);\n\n\/\/ cancel\nsettimeout(() =&gt; {\n  interval.clear();\n}, 5000);\n\n\n\n\/\/ use `settimeout`\nfunction mysetinterval(callbackfn, delay) {\n  let timerid = null;\n  let start = date.now();\n  let count = 0;\n\n  \/\/ loop\n  function loop() {\n    const drift = date.now() - start - count * delay;\n    count += 1;\n\n    timerid = settimeout(() =&gt; {\n      callbackfn();\n      loop();\n    }, delay - drift);\n  }\n\n  \/\/ run loop\n  loop();\n\n  return {\n    clear: () =&gt; cleartimeout(timerid),\n  }\n}\n\nconst interval = mysetinterval(() =&gt; {\n  console.log('interval tick');\n}, 1000);\n\n\/\/ cancel\nsettimeout(() =&gt; {\n  interval.clear();\n}, 5000);\n<\/pre>\n<p> \u767b\u5f55\u540e\u590d\u5236 <\/p>\n<hr>\n<h3> \u5b9e\u73b0 settimeout() <\/h3>\n<pre>function setTimeout(callbackFn, delay) {\n  let elapsedTime = 0;\n  const interval = 100;\n\n  const intervalId = setInterval(() =&gt; {\n    elapsedTime += interval;\n\n    if (elapsedTime &gt;= delay) {\n      clearInterval(intervalId);\n      callbackFn();\n    }\n  }, interval);\n}\n\n\/\/ Usage example\nmySetTimeout(() =&gt; {\n  console.log('This message is displayed after 2 seconds.');\n}, 2000);\n<\/pre>\n<p> \u767b\u5f55\u540e\u590d\u5236 <\/p>\n<hr>\n<h2> \u53c2\u8003 <\/h2>\n<ul>\n<li>\u7a97\u53e3\uff1asettimeout() \u65b9\u6cd5 &#8211; mdn<\/li>\n<li>\u7a97\u53e3\uff1asetinterval() \u65b9\u6cd5 &#8211; mdn<\/li>\n<li>\u7a97\u53e3\uff1aclearinterval() \u65b9\u6cd5 &#8211; mdn<\/li>\n<li>\u7a97\u53e3\uff1acleartimeout() \u65b9\u6cd5 &#8211; mdn<\/li>\n<li>2715\u3002\u8d85\u65f6\u53d6\u6d88 &#8211; leetcode<\/li>\n<li>2725\u3002\u95f4\u9694\u53d6\u6d88 &#8211; leetcode<\/li>\n<li>2622\u3002\u6709\u65f6\u95f4\u9650\u5236\u7684\u7f13\u5b58 &#8211; leetcode<\/li>\n<li>2627\u3002\u53cd\u8df3 &#8211; leetcode<\/li>\n<li>2676\u3002\u6cb9\u95e8 &#8211; leetcode<\/li>\n<li>\u901f\u7387\u9650\u5236 &#8211; wikipedia.org<\/li>\n<li>28\u3002\u5b9e\u73b0clearalltimeout() &#8211; bfe.dev<\/li>\n<li>4.\u5b9e\u73b0\u57fa\u672c\u7684throttle() &#8211; bfe.dev<\/li>\n<li>5.\u4f7f\u7528\u524d\u5bfc\u548c\u5c3e\u968f\u9009\u9879\u5b9e\u73b0throttle() &#8211; bfe.dev<\/li>\n<li>6.\u5b9e\u73b0\u57fa\u672c\u7684 debounce() &#8211; bfe.dev<\/li>\n<li>7.\u4f7f\u7528\u524d\u5bfc\u548c\u5c3e\u968f\u9009\u9879\u5b9e\u73b0 debounce() &#8211; bfe.dev<\/li>\n<li>javascript \u5f02\u6b65\uff1a\u7ec3\u4e60\u3001\u5b9e\u8df5\u3001\u89e3\u51b3\u65b9\u6848 &#8211; w3resource<\/li>\n<li>\u4f1f\u5927\u7684\u524d\u7aef<\/li>\n<\/ul>\n<p>\u4ee5\u4e0a\u5c31\u662f\u8ba1\u65f6\u5668 &#8211; JavaScript \u6311\u6218\u7684\u8be6\u7ec6\u5185\u5bb9\uff0c\u66f4\u591a\u8bf7\u5173\u6ce8\u7c73\u4e91\u5176\u5b83\u76f8\u5173\u6587\u7ae0\uff01<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u60a8\u53ef\u4ee5\u5728 hub \u4ed3\u5e93\u4e2d\u627e\u5230\u8fd9\u7bc7\u6587\u7ae0\u4e2d\u7684\u6240\u6709\u4ee3\u7801\u3002 \u5f02\u6b65\u7f16\u7a0b\u5b9a\u65f6\u5668\u76f8\u5173\u7684\u6311\u6218 \u6709\u65f6\u95f4\u9650\u5236\u7684\u7f13\u5b58 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(() =&gt; { this._cache.delete(key); }, duration), }); return found; } get(key) { if (this._cache.has(key)) { return this._cache.get(key); } else { return -1; } [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[16],"tags":[],"class_list":["post-2263","post","type-post","status-publish","format-standard","hentry","category-16"],"_links":{"self":[{"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/posts\/2263","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/comments?post=2263"}],"version-history":[{"count":0,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/posts\/2263\/revisions"}],"wp:attachment":[{"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/media?parent=2263"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/categories?post=2263"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/tags?post=2263"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}