Inicialmente, tenía un código para realizar ciertas operaciones periódicamente. Aunque encontré problemas extraños de rendimiento y sincronización.
Aislé el bucle principal en su propio script a continuación.
let sleepTime = 50 //milliseconds var sleep = (ms) => new Promise(res => setTimeout(res, ms)) let state = { stopCalled: false, countLoops: 0, lastLoopTime: 0, loopDuration: 0, badLoops: [], badSleeps: [] } let data = [1, 2, 3, 5, 1, 1, 1, 5, 1, 3, 1, 5, 4] async function startLoop() { //necessary for first loopDuration state.lastLoopTime = Date.now() - 50 while (true) { if (state.stopCalled) return state.countLoops++ state.loopDuration = Date.now() - state.lastLoopTime state.lastLoopTime = Date.now() if (state.loopDuration > 100) { state.badLoops.push(state.loopDuration) console.log(`Bad loop duration: ${state.loopDuration}`) } //do some random work let rand = randomInteger(1, 7) for (let i = 0; i <data.length; i++) { if (data[i] === rand) continue data[i] = randomInteger(1, 7) } let initialTime = Date.now() await sleep(sleepTime) let actualSleepDuration = Date.now() - initialTime //sleep duration should be <=50 milliseconds if (actualSleepDuration > 100) { state.badSleeps.push(actualSleepDuration) console.log(`Bad sleep duration: ${actualSleepDuration}`) } } } function randomInteger(min, max) { return Math.round((max - min) * Math.random()) + min }Un resumen de lo que hace el código: después de llamar manualmente a startLoop, debe ejecutar el ciclo periódicamente cada 50 ms. Esperaba una imprecisión de +/- 5 ms, lo cual está bien.
Sin embargo, la función de suspensión/setTimeout se vuelve extremadamente imprecisa hasta 1 minuto completo, especialmente después de funcionar durante mucho tiempo.
Entiendo que setTimeout es más preciso si no hay un código de bloqueo, en este caso, este es el único script que se ejecuta, lo que no tiene sentido por qué hay tanto retraso.
¿Hay una forma más precisa de ejecutar una función?
Realice dos pruebas De: una de Electron 17.0.1 otra de Node JS 17.5.0 REPL con .load file.js
Después de muchas pruebas, descubrí que Chrome acelera las pestañas/ventanas de fondo de Chrome 88 , lo cual es ideal para sitios web en computadoras portátiles para ahorrar energía.
Pero realmente malo para las aplicaciones de electrones (use el motor Chromium), eso no debe ser acelerado.
Para solucionar esto debes cambiar backgroundThrottling a false , que por defecto es true
const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { backgroundThrottling: false, } })Un extracto del documento de estrangulamiento :
Esto afecta tanto a setInterval como a setTimeout, en los que se basan todos los temporizadores de JavaScript sin bloqueo.