簡體   English   中英

如何運行由於實時數據而導致JavaScript變化的變量?

[英]How do I make a running total of a variable that changes in JavaScript due to live data?

我需要測量以下代碼在幾秒鍾內調用振動函數的時間長度並顯示我工作的秒數。 但是,我不知道如何創建一個運行總計,以便每次調用vibrate()時,它都會以秒為單位測量長度,然后將其添加到運行總計中。

function goodValue() {
    startTime = new Date()
    string1 = 'GOOD!!! :)'
    displayValue('Angles', string1)
}

var startTime = {}
function badValue() {
    var endTime = new Date()
    vibrate1(1500)
    string2 = 'BAD!!! :('
    displayValue('Angles', string2)
    var timeDiff = endTime - startTime //in ms
    // strip the ms
    timeDiff /= 1000

    // get seconds 
    seconds = Math.round(timeDiff);
    displayValue('TotalTime', + seconds);
}

現在應該可行了。 它假設你叫goodAngle()當應用程序識別一個好的角度,和badAngle()當應用程序識別角度不好。

var totalTime = 0
var startTime = false

function goodAngle() {
  if (startAngle) {
    timeDiff = (Date.now() - startTime) / 1000
    console.log('timeDiff: %s seconds', timeDiff)
    totalTime += timeDiff
    console.log('total timeDiff: %s seconds', timeDiff)
    string1 = 'GOOD!!! :)'
    displayValue('Angles', string1)
    displayValue('BadPostureTime', Math.round(timeDiff))
    startTime = false // So it  can't be called again unless there's a badAngle first
  }
}

function badAngle() {
  if (!startTime) {
    // Only set startTime if there isn't a current timer running
    startTime = Date.now()
    vibrate1(1500)
    string2 = 'BAD!!! :('
    displayValue('Angles', string2)
  }
}

很難說你的代碼應該做什么,但我建議制作一個可以包裝你的vibrate1實現的函數。 measureTime函數將函數作為參數(在您的情況下為vibrate)並返回一個函數,該函數具有記錄執行時間的屬性totalTime 請注意,它使用performance.now()而不是Date對象。 請參閱https://developer.mozilla.org/fr/docs/Web/API/Performance/now以供參考。

function measureTime(fn) {
  const returnedFn = function measuredFunction (arg) {
    const start = performance.now();
    fn(arg);
    const end = performance.now();
    returnedFn.totalTime = returnedFn.totalTime + ((end - start) / 1000); 
  };
  returnedFn.totalTime = 0;

  return returnedFn;
}

const measuredVibrate = measureTime(vibrate1);


displayValue(measuredVibrate.totalTime);

跳到擴展的代碼段以獲取此問題的答案。 其余示例涉及測量其他相關指標。

衡量每個人的時間

如果要測量函數的執行時間,可以將其包裝在另一個使用console.time()console.timeEnd()函數中:

 function measure (fn, label = fn.name) { return function () { try { console.time(label) return fn.apply(this, arguments) } finally { console.timeEnd(label) } } } function delay (ms) { const now = Date.now() while (Date.now() - now < ms) { } } // wrap the function that needs to be tested const timedDelay = measure(delay) timedDelay(100) timedDelay(10) 

這個measure()函數有一些不錯的功能:

  • 始終保留原始函數的返回值
  • 始終保留原始函數的拋出錯誤
  • 如果原始函數拋出錯誤,則仍會記錄所用的時間
  • 可選的label參數用於標記控制台中顯示的時間
  • label默認為原始函數的名稱
  • 原始函數完全接收傳遞的上下文和參數

要測量異步函數,您可以使用以下內容,除了上述功能之外,還可以通過遞增label中使用的數字來處理並發調用:

 function measureAsync (fn, name = fn.name) { let index = 0 return async function () { const label = `${name} (${++index})` try { console.time(label) return await fn.apply(this, arguments) } finally { console.timeEnd(label) } } } function delay (ms) { return new Promise(resolve => { setTimeout(resolve, ms) }) } // wrap the async function that needs to be tested const timedDelay = measureAsync(delay) timedDelay(1000) timedDelay(100) timedDelay(500) 

測量總時間

使用上述兩種實現,您可以使用Performance API修改它們,以測量累積時間:

同步

 function measureTotal (fn, label = fn.name) { return Object.assign(function measured () { try { performance.mark(label) return fn.apply(this, arguments) } finally { performance.measure(label, label) const [{ duration }] = performance.getEntriesByName(label, 'measure') const total = measured.total += duration performance.clearMarks(label) performance.clearMeasures(label) console.log(`${label}: ${total.toFixed(3)}ms`) } }, { total: 0 }) } function delay (ms) { const now = Date.now() while (Date.now() - now < ms) { } } // wrap the function that needs to be tested const timedDelay = measureTotal(delay) timedDelay(100) timedDelay(10) timedDelay(50) console.log('total:', timedDelay.total) 

異步

 function measureTotalAsync (fn, name = fn.name) { let index = 0 return Object.assign(async function measured () { const label = `${name} (${++index})` try { performance.mark(label) return await fn.apply(this, arguments) } finally { performance.measure(label, label) const [{ duration }] = performance.getEntriesByName(label, 'measure') const total = measured.total += duration performance.clearMarks(label) performance.clearMeasures(label) console.log(`${label}: ${total.toFixed(3)}ms`) } }, { total: 0 }) } function delay (ms) { return new Promise(resolve => { setTimeout(resolve, ms) }) } // wrap the async function that needs to be tested const timedDelay = measureTotalAsync(delay) Promise.all([ timedDelay(1000), timedDelay(100), timedDelay(500) ]).finally(() => { console.log('total:', timedDelay.total) }) 

參考

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM