亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

js如何實現0ms延時定時器

發布時間:2021-07-27 13:42:40 來源:億速云 閱讀:121 作者:小新 欄目:開發技術

小編給大家分享一下js如何實現0ms延時定時器,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

示例如下

(function() {
 var timeouts = [];
 var messageName = "zero-timeout-message";
 // Like setTimeout, but only takes a function argument.  There's
 // no time argument (always zero) and no arguments (you have to use a closure)
 function setZeroTimeout(fn) {
  timeouts.push(fn);
  window.postMessage(messageName, "*");
 }
 function handleMessage(event) {
  if (event.source == window && event.data == messageName) {
   event.stopPropagation();
   if (timeouts.length > 0) {
    var fn = timeouts.shift();
    fn();
   }
  }
 }

 window.addEventListener("message", handleMessage, true);

 // Add the one thing we want added to the window object.
 window.setZeroTimeout = setZeroTimeout;
})();

作者還提供了一個demo頁面【3】,通過于setTimeout(0)進行對比,在我瀏覽器的執行結果如下:

100 iterations of setZeroTimeout took 15 milliseconds.
100 iterations of setTimeout(0) took 488 milliseconds.

根據結果對比來看,setZeroTimeout執行比setTimeout快了上百倍,這是一個巨大的提升。今天想討論的是除了上述這種方式,還可以通過哪些方式來實現一個0ms延時的定時器呢,首先,我們要確定一下我們自定義的定時器是異步的,其次是盡可能早的被執行。說起異步,js提供了好幾種解決方案,我們可以逐一去驗證。

在深入討論各種實現方式之前,約定提供的setTimeout對比版本如下,后面自定義實現的方案都將和setTimeout版本的執行時間進行對比,代碼比較簡單:

(function() {
 let i = 0;
 const start = Date.now();
 function test() {
  if(i++ < 100) {
   setTimeout(test);
  } else {
   console.log('setTimeout執行時間:', Date.now() - start);
  }
 }
 setTimeout(test);
})();

queueMicrotask

queueMicrotask這個api可以添加一個微任務,使用比較簡單,直接傳遞一個回調函數即可,具體實現如下:

(function() {
 function setZeroTimeout(fn) {
  queueMicrotask(fn);
 }
 let i = 0;
 const start = Date.now();
 function test() {
  if(i++ < 100) {
   setZeroTimeout(test);
  } else {
   console.log('setZeroTimeout執行時間:', Date.now() - start);
  }
 }
 setZeroTimeout(test);
})();

通過和setTimeout版本進行對比,最終結果如下:

setZeroTimeout執行時間: 2
setTimeout執行時間: 490

關于這個API的介紹在MDN上有詳細的說明,就不展開介紹了,這里多說一點,根據規范文檔的說明,大多數情況下,推薦使用requestAnimationFrame()和requestIdleCallback()等api,因為queueMicrotask會阻塞渲染,在很多時候都不是一種好的實踐。

async/await

async/await對于前端開發人員來說已經是必不可少的了,這里我們也可以用來實現:

(function() {
 async function setAsyncTimeout(fn) {
  Promise.resolve().then(fn);
 }
 let i = 0;
 const start = Date.now();
 async function test() {
  if (i++ < 100) {
   await setAsyncTimeout(test);
  } else {
   console.log('setAsyncTimeout執行時間:', Date.now() - start);
  }
 }
 setAsyncTimeout(test);
})();

通過和setTimeout版本進行對比,最終結果如下:

setAsyncTimeout執行時間: 2
setTimeout執行時間: 490

如果不嫌麻煩,還可以通過Promise來實現,其實都是大同小異,無非多些點代碼,這里就省略了。

MessageChannel

MessageChannel允許我們創建一個新的消息通道,并通過它的兩個MessagePort屬性發送數據,MessageChannel提供端口的概念,實現端口之間的通信,比如worker/iframe之間的通信。

(function() {
 const channel = new MessageChannel();
 function setMessageChannelTimeout(fn) {
  channel.port2.postMessage(null);
 }
 channel.port1.onmessage = function() {
    test();
 };
 let i = 0;
 const start = Date.now();
 function test() {
  if(i++ < 100) {
   setMessageChannelTimeout(test);
  } else {
   console.log('setMessageChannelTimeout執行時間:', Date.now() - start);
  }
 }
 setMessageChannelTimeout(test);
})();

通過和setTimeout版本進行對比,最終結果如下:

setMessageChannelTimeout執行時間: 4
setTimeout執行時間: 490

第三種方式運行時間比前面兩種更長些,因為通過MessageChannel產生的是宏任務,其他兩種是微任務,微任務執行靠前,且會阻塞主線程,因此時間會長一點。

以上是“js如何實現0ms延時定時器”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

js
AI

东兴市| 孟村| 商城县| 中卫市| 勃利县| 台州市| 崇仁县| 江城| 庆城县| 北辰区| 右玉县| 兴仁县| 马鞍山市| 兴隆县| 绿春县| 涪陵区| 晋江市| 郓城县| 上犹县| 增城市| 鱼台县| 鄯善县| 泽普县| 贞丰县| 防城港市| 新津县| 广州市| 广水市| 浦江县| 阳原县| 晴隆县| 彭泽县| 平凉市| 唐河县| 青龙| 东至县| 浪卡子县| 城口县| 宣武区| 来凤县| 高台县|