自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

坑??!前端倒計(jì)時(shí)有誤差!讓公司損失了幾十萬(wàn)!

開(kāi)發(fā) 前端
前幾天聽(tīng)說(shuō)公司某個(gè)項(xiàng)目組,由于不對(duì)定時(shí)器進(jìn)行誤差處理,間接導(dǎo)致?lián)p失了幾十萬(wàn)。。還被領(lǐng)導(dǎo)公開(kāi)批評(píng)了。因?yàn)槎〞r(shí)器誤差,導(dǎo)致了公司幾個(gè)單子處理失敗。。。白白損失了 money。

前幾天聽(tīng)說(shuō)公司某個(gè)項(xiàng)目組,由于不對(duì)定時(shí)器進(jìn)行誤差處理,間接導(dǎo)致?lián)p失了幾十萬(wàn)。。還被領(lǐng)導(dǎo)公開(kāi)批評(píng)了。因?yàn)槎〞r(shí)器誤差,導(dǎo)致了公司幾個(gè)單子處理失敗。。。白白損失了 money。

"倒計(jì)時(shí)誤差"是前端開(kāi)發(fā)中的經(jīng)典問(wèn)題,也是面試官考察候選人問(wèn)題分析能力的高頻考點(diǎn)

一、誤差從何而來(lái)?

核心問(wèn)題: 瀏覽器主線程的阻塞

前端倒計(jì)時(shí)通?;?/span>setIntervalsetTimeout實(shí)現(xiàn),而這兩個(gè)API存在以下問(wèn)題:

  • 時(shí)間間隔不可靠:實(shí)際執(zhí)行間隔 >= 設(shè)定值
  • 事件循環(huán)被阻塞:同步代碼、長(zhǎng)任務(wù)、網(wǎng)絡(luò)請(qǐng)求等
  • 標(biāo)簽頁(yè)休眠:瀏覽器后臺(tái)運(yùn)行時(shí)計(jì)時(shí)器會(huì)被限流(最小延遲4ms甚至更長(zhǎng))
  • 系統(tǒng)休眠:電腦睡眠/鎖屏?xí)?dǎo)致計(jì)時(shí)完全暫停
// 典型的誤差累計(jì)示例
let count = 10
const timer = setInterval(() => {
  count--
  console.log(count)
}, 1000)
// 實(shí)際誤差會(huì)隨時(shí)間逐漸增大

二、五大解決方案

1. 動(dòng)態(tài)校準(zhǔn)法(基礎(chǔ)版)

function accurateTimer(fn, interval) {
let expected = Date.now() + interval
let timeout

const tick = () => {
    const drift = Date.now() - expected // 計(jì)算偏差
    fn()
    
    expected += interval // 更新下次預(yù)期時(shí)間
    timeout = setTimeout(tick, Math.max(0, interval - drift))
  }

  timeout = setTimeout(tick, interval)
return() => clearTimeout(timeout)
}
  • 優(yōu)點(diǎn): 簡(jiǎn)單有效
  • 缺點(diǎn): 無(wú)法解決系統(tǒng)休眠等長(zhǎng)時(shí)間阻塞

2. Web Worker 計(jì)時(shí)

將計(jì)時(shí)器移至獨(dú)立線程,避免主線程阻塞

// main.js
const worker = new Worker('timer.worker.js')
worker.postMessage({ cmd: 'start', interval: 1000 })

// timer.worker.js
self.addEventListener('message', (e) => {
  setInterval(() => {
    self.postMessage('tick')
  }, e.data.interval)
})
  • 優(yōu)點(diǎn): 隔離主線程影響
  • 缺點(diǎn): 仍受系統(tǒng)休眠影響

3. 服務(wù)器時(shí)間同步

通過(guò)接口獲取服務(wù)器時(shí)間進(jìn)行校準(zhǔn)

async function syncTime() {
  const start = Date.now()
  const res = await fetch('/api/time')
  const serverTime = await res.json()
  const latency = Date.now() - start
  
  return serverTime + Math.floor(latency/2) // 假設(shè)網(wǎng)絡(luò)延遲對(duì)稱
}

最佳實(shí)踐:

  • 首次加載時(shí)校準(zhǔn)
  • 定時(shí)輪詢同步(例如每1分鐘)
  • 使用 WebSocket 保持時(shí)間同步

4. Performance API 高精度計(jì)時(shí)

使用performance.now()獲取亞毫秒級(jí)時(shí)間戳

const start = performance.now()

function check() {
  const elapsed = performance.now() - start
  if(elapsed >= 1000) {
    // do something
    start = performance.now() 
  }
  requestAnimationFrame(check)
}

特點(diǎn):

  • 精度可達(dá)微秒級(jí)
  • 不受系統(tǒng)時(shí)間修改影響
  • 適合需要高精度計(jì)算的場(chǎng)景

5. 頁(yè)面可見(jiàn)性API優(yōu)化

在標(biāo)簽頁(yè)不可見(jiàn)時(shí)降低更新頻率

document.addEventListener('visibilitychange', () => {
  if(document.hidden) {
    clearInterval(timer)
    // 記錄剩余時(shí)間
  } else {
    // 重新校準(zhǔn)后啟動(dòng)
  }
})

三、生產(chǎn)環(huán)境最佳實(shí)踐

根據(jù)場(chǎng)景選擇組合方案:

場(chǎng)景

推薦方案

誤差控制

秒殺倒計(jì)時(shí)

服務(wù)器時(shí)間 + WebSocket + 動(dòng)態(tài)校準(zhǔn)

<100ms

問(wèn)卷計(jì)時(shí)

Web Worker + 本地存儲(chǔ)恢復(fù)

<1s

動(dòng)畫倒計(jì)時(shí)

RAF + 性能監(jiān)測(cè)

16ms以內(nèi)

四、終極解決方案架構(gòu)

圖片

責(zé)任編輯:武曉燕 來(lái)源: 前端之神
相關(guān)推薦

2022-10-21 15:42:21

倒計(jì)時(shí)鴻蒙

2014-03-21 13:46:45

2014-08-18 14:30:27

Android倒計(jì)時(shí)

2011-04-11 09:17:28

Ubuntu倒計(jì)時(shí)

2017-07-20 16:21:52

UICountDownTidelay

2015-03-23 17:58:04

驗(yàn)證碼倒計(jì)時(shí)并行

2011-04-11 09:50:56

Ubuntu 11.0

2014-02-18 10:36:33

2022-06-14 08:45:27

瀏覽器IEWindows

2013-10-08 09:24:39

Windows 8.1Windows 8

2013-04-09 10:01:18

微軟Windows XP

2013-10-10 09:23:15

Android 4.4Kitkat

2019-12-13 19:37:00

BashLinux命令

2020-10-28 17:54:49

成都信息安全

2012-03-28 09:37:07

Ubuntu 12.0倒計(jì)時(shí)

2012-12-28 13:50:00

2015-01-21 16:07:57

Android源碼驗(yàn)證碼倒計(jì)時(shí)

2025-04-11 08:42:37

JavaScript倒計(jì)時(shí)前端

2013-06-06 11:27:52

iRadioWWDC2013
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)