日韩欧美人妻无码精品白浆,www.大香蕉久久网,狠狠的日狠狠的操,日本好好热在线观看

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

你不知道的setTimeout

liguoquan
2024年12月27日 12:39 本文熱度 1232
:你不知道的setTimeout


你不知道的setTimeout

前言

setTimeout() 我們在日常工作中經(jīng)常使用,最近做了一個功能是關(guān)于setTimeout()的,總結(jié)了一些用法。

在這篇文章中,你將了解 setTimeout() 方法——它是什么以及如何在你的程序中使用它。

以下是我在這篇快速指南中要介紹的內(nèi)容:

  • JavaScript 中的  setTimeout() 基本語法
  • 進階語法:防抖、代碼邏輯執(zhí)行時間可能比定時器時間間隔要長如何處理
  • setTimeout()的定時器是否精準(zhǔn)
  • 定時器在非激活tab或者熄屏的時候還會按照預(yù)期去執(zhí)行嗎
  • 定時器如何進行時間糾正
  • 簡單比較下scheduler.yield

基本的語法

scss
代碼解讀
復(fù)制代碼
setTimeout(code) setTimeout(code, delay) setTimeout(functionRef) setTimeout(functionRef, delay) setTimeout(functionRef, delay, param1) setTimeout(functionRef, delay, param1, param2) setTimeout(functionRef, delay, param1, param2, /* …, */ paramN)

例如我們寫個最簡單的

我們來添加一個參數(shù)進行測試 如下,可以打印出來獲取到的參數(shù)params1和params2

返回值

返回值 timeoutID 是一個正整數(shù),表示由 setTimeout() 調(diào)用創(chuàng)建的定時器的標(biāo)識符??梢詫⑦@個值傳遞給 clearTimeout() 來取消該定時器。

我們嘗試在1秒的時候?qū)imerId進行清除,測試下是否可以正常打印,如你所料,不會打印timerId內(nèi)的數(shù)據(jù)

進階用法

1 防抖(常用于表單提交)

我們在表單提交的時候,比如希望表單的提交按鈕在1秒內(nèi)之內(nèi)只生效一次,可以利用settimeout來實現(xiàn)。

如下,假如在頁面上有一個id為submitBtn的按鈕,添加了一個點擊事件,當(dāng)1秒內(nèi)每次點擊都會清除之前的timeoutId,不會執(zhí)行提交的邏輯。從而確保只有在最后一次點擊后的1秒內(nèi)沒有再次點擊時,才會執(zhí)行實際的操作。

javascript
代碼解讀
復(fù)制代碼
    let submitBtn = document.getElementById("submitBtn");     let timeoutId;     function onTest() {         if (timeoutId) {             clearTimeout(timeoutId);         }         timeoutId = setTimeout(function() {             // 在這里編寫提交邏輯             alert("按鈕被點擊了!");         }, 1000);     }     submitBtn.addEventListener("click", onTest);

2 優(yōu)先展示用戶希望看到的內(nèi)容(利用JS事件機制)

假如我們有一個人員的新增表單,部門樹的下拉框有10K條數(shù)據(jù),假如我們還沒有虛擬下拉樹,數(shù)據(jù)的渲染會很慢, 打開這個新增的表單可能會有3到5S的延遲后表單才會打開。

我們可以將這個部門樹的下拉值綁定寫在了settimeout內(nèi),等主線程的任務(wù)執(zhí)行后,再執(zhí)行綁定部門樹的操作,可以優(yōu)先將其他的內(nèi)容展示出來后再進行部門樹的綁定。

3 替代setInterval防止請求阻塞

比如我們有個需求: 1秒的間隔輪詢服務(wù)器,頁面展示內(nèi)容

正常的話可以用setInterval沒什么問題,

假如請求的接口可能因網(wǎng)絡(luò)延遲、服務(wù)器無響應(yīng)以及許多其他的問題而導(dǎo)致請求無法在分配的時間內(nèi)完成(假如服務(wù)器處理了3秒)

我們把請求的間隔設(shè)置為1秒,實際的接口在2秒多,就會造成請求的阻塞,其實我們想實現(xiàn)的是在一次接口請求結(jié)束后再發(fā)起下一次請求

如下方的截圖

接口固定在大約2秒返回,就會導(dǎo)致永遠有幾個請求在阻塞,跟我們的預(yù)想不同

我們對上面的代碼進行改造如下

 實現(xiàn)如果如下,我們保證有一個請求在pending,會在一個請求發(fā)出后,再進行發(fā)送下一次請求

代碼解釋如下

在上面的代碼片段中,聲明了一個具名函數(shù) loop(),并被立即執(zhí)行。loop() 在完成代碼邏輯的執(zhí)行后,會在內(nèi)部遞歸調(diào)用 setTimeout()。雖然該模式不保證以固定的時間間隔執(zhí)行,但它保證了上一次定時任務(wù)在遞歸前已經(jīng)完成。

可能遇到的場景

1 settimeout這個定時器準(zhǔn)嗎

答案:正常場景下是準(zhǔn)的,某些場景下是不準(zhǔn)的,

有很多因素會導(dǎo)致超時比設(shè)定的預(yù)期值更久 如需查看更多的原因點擊我

嵌套多次的時候會有4ms的延遲(可以點擊下方的例子進行測試)

點擊我直接看在線例子

當(dāng)嵌套多次的結(jié)果如下,就不做詳細介紹了,了解就行。目前我沒想到哪些場景下settimeout會被嵌套調(diào)用5次,就不做繼續(xù)研究,我們只需要知道這個概念就行,等出現(xiàn)這個問題了有個排查方向就行

主線程有耗時的任務(wù)

我們做個實驗,我們對id為main對dom進行2萬次的修改innerHtml,在控制臺打印時間,

原本2秒變?yōu)榱?秒,所以settimeout 有時候并不會按照預(yù)期的時間間隔來執(zhí)行

這里其實就涉及到了js的事件為單線程機制,我們用performance簡單分析下,看到有個3865ms的parse HTML的,然后執(zhí)行Run Microtasks也就是微任務(wù),也就是等我們的同步任務(wù)執(zhí)行后,再去執(zhí)行settimeout內(nèi)的東西

在非活動標(biāo)簽的tab,待機下的settimeout還會按照預(yù)期執(zhí)行嗎?

以下的測試是在chrome的mac版本進行測試

代碼很簡單,寫了個2秒的定時器

待機狀態(tài)

tab非激活

過幾分鐘后,定時器會從2秒變?yōu)?分鐘

由此我們得知,在瀏覽器激活的時候,settimeout 會按照我們的預(yù)期去執(zhí)行,在非激活(tab不選中過段時間、電腦處于待機狀態(tài))下,定時器會按照1min一次去執(zhí)行,

但是有種特殊場景,audio假如正在播放,此時頁面的settimeout會被當(dāng)作激活狀態(tài)

settimeout 時間糾正

當(dāng)然,因為js的事件機制,settimeout存在時間偏差,就會存在時間糾正,下面介紹了兩個js的時間糾正方式,雖然我試用下來不太理想,也可能是我的姿勢不對,有更好的方式歡迎和我討論

計算時間差(并不能完全避免,只能糾正)

直接在網(wǎng)上抄寫了個例子。 使用 setTimeout 進行計時,每次計時都會用系統(tǒng)時間修復(fù)時間差

js
代碼解讀
復(fù)制代碼
  function timer_setTimeout() {     const speed = 1000; // 設(shè)置定時器的間隔速度為1000毫秒(1秒)     let countTime = 0; // 初始化計時器計數(shù)變量     let start = new Date().getTime(); // 記錄計時開始時的時間戳     // 定義計時器的執(zhí)行函數(shù)     function run() {       countTime++; // 每次執(zhí)行時遞增計時器的計數(shù)       // 計算按照計時器當(dāng)前速度實際經(jīng)過的時間(countTime * 速度)       let realTime = (countTime * speed);       // 計算從計時開始到現(xiàn)在系統(tǒng)經(jīng)過的時間       let sysTime = (Date.now() - start);       // 計算實際時間和理想時間之間的差異       let patch = (sysTime - realTime);       // 使用系統(tǒng)時間進行修復(fù),調(diào)整下一次setTimeout的延遲時間       // 通過設(shè)置speed - diff,嘗試校正setTimeout的延遲,以補償偏差       window.setTimeout(run, (speed - patch));       // 更新頁面元素timeoutDom的文本內(nèi)容,顯示當(dāng)前計時器的值       timeoutDom.innerText = `setTimeout: ${countTime}`;     }     // 啟動計時器,初始調(diào)用run函數(shù),并設(shè)置延遲為speed     window.setTimeout(run, speed);   }   // 調(diào)用函數(shù),創(chuàng)建并啟動setTimeout計時器   timer_setTimeout();

webworker(測試下來效果不好)

javascript
代碼解讀
復(fù)制代碼
 console.log(new Date());  for (let index = 0; index < 20000; index++) {    document.getElementById('main').innerHTML += index;  }  function timer_worker() {    // 創(chuàng)建一個Blob對象,用于生成一個可以在Web Worker中執(zhí)行的JavaScript代碼URL    const blob = new Blob(      [        `let countTime = 0;      self.setInterval(() => { // 在Web Worker的上下文中設(shè)置一個定時器        countTime++; // 每次定時器觸發(fā)時遞增計數(shù)器        self.postMessage(countTime); // 使用postMessage方法發(fā)送計數(shù)器的值到主線程      }, 5000);` // 定時器的時間間隔設(shè)置為1秒      ],      { type: 'application/javascript' }    ); // 指定Blob的內(nèi)容類型為JavaScript    // 使用URL.createObjectURL方法創(chuàng)建一個可以被Web Worker使用的URL    const worker = new Worker(URL.createObjectURL(blob));    // 設(shè)置Web Worker的onmessage事件處理器    // 當(dāng)Web Worker使用postMessage發(fā)送消息時,該處理器會被觸發(fā)    worker.onmessage = (ev) => {      // 更新DOM元素workerDom的文本內(nèi)容,顯示從Web Worker接收到的計時器值      console.log(new Date() + ` worker: ${ev.data}`);    };  }  timer_worker();

遇到長的任務(wù)的時候,還是會延遲執(zhí)行

scheduler.yield

在查找 setTimeout 的資料的時候,發(fā)現(xiàn)了有一個比較好的東西,scheduler.yield, 感興趣的老板可以點擊我進行體驗,目前兼容性不好(24年8月21日的才支持),不做詳細介紹。

兼容性如下 

 總結(jié)一句話

使用 setTimeout 是將事件插入在隊列的結(jié)尾。yield而是發(fā)送到隊列的前面。這樣,既可以讓步以提高網(wǎng)站上的輸入響應(yīng)速度,又可以確保在讓步完成的工作不會延遲。

參考文檔

總結(jié)

  1. setTimeout 可以實現(xiàn)延遲的一些事件,比如多少秒后返回首頁等
  2. setTimeout 可以通過一定時間內(nèi)事件只執(zhí)行一次實現(xiàn)防抖
  3. setTimeout 可以替代 setInterval實現(xiàn)更好的輪詢
  4. setTimeout 可以通過js事件的異步機制,優(yōu)先展示用戶關(guān)注的內(nèi)容
  5. setTimeout 的事件定時器在某些場景下定時器不準(zhǔn),大部分場景下是準(zhǔn)的,如果要求比較精確需要可以進行時間差的修正
  6. setTimeout 在熄屏或者非激活tab的場景下,計時器會延長變?yōu)?min執(zhí)行一次
  7. setTimeout 是把事件插入到尾部,未來我們可以使用 scheduler.yield的暫停頁面的操作,提升用戶體驗 、

該文章在 2024/12/27 12:39:50 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運作、調(diào)度、堆場、車隊、財務(wù)費用、相關(guān)報表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點,圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務(wù)都免費,不限功能、不限時間、不限用戶的免費OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

人人干人人艹人人爽| 日韩第一区二区| 午夜伦理神马久久久久久久| 人妻。久久久| 欧美亚洲国产精品久久3P| 双插做爱视频| 中文字幕啪啪啪啪啪啪啪| 亚洲无码人妻激情视频| 综合久色欧美综合亚洲| 国产精品一卡二卡免费视频| 欧美白丝操逼x| 91Av三区| 欧美黑人一级性黄片| 成人全彩在线观看日韩国产欧美| 免费成人久久黄色片| h网站在线国产| 国产精伦一区二区电影| 亚洲熟女99大香蕉综合| 污污的小视频 一区| 91久久人爽人人添人人澡| 日韩欧美美女少妇一区二区| 色多多精品久久久| 汉服色情aa一区二区| 国产福利三级片| 久久青青精品麻豆热| 亚欧一二三区| 中文字幕人妻熟女美腿丝袜| 精品视频个久久| xxx99| 人人干夜夜爽| 日本精品综合在| 高青一区二区| 亚洲日韩 在线观看 视频一区| 人妻无码1区2区3区| 欧美成人免费夫妻性生活片 | 久久丁香五月亚洲| 亚洲精品不卡久久久久| 大香蕉之大香蕉5| 亚洲五月丝袜| 九九日韩视频6| 高清成人一区91久久|