如何解决Electron应用中setInterval定时同步网络时钟不生效问题
问题根源
setInterval使用错误:你写的setInterval(getNetTime(),1000)中getNetTime()加了括号,会立即执行该函数,把执行结果(undefined)传给定时器,定时器实际上没有绑定要重复执行的任务,自然不会定时触发。- 重复注册IPC监听:
getNetTime函数内部每次执行都会新增一个ipcRenderer.on('datetime')的监听器,重复执行会导致同一事件触发多次回调,属于资源浪费且有逻辑隐患。 - 主进程未实现重复请求逻辑:当前主进程的时间接口请求只在初始化时执行一次,就算渲染侧逻辑正常,也拿不到更新后的时间数据。
解决方案
第一步:修改主进程逻辑
把时间请求封装成可调用的函数,同时监听渲染进程的时间获取请求,收到请求后触发接口调用:
// 主进程main.js新增/修改内容 const { net, ipcMain } = require('electron') // 封装时间请求函数 function fetchNetTime() { const request = net.request('http://api.k780.com:88/?app=life.time&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json') request.on('response', (response) => { response.on('data', (chunk) => { let result = JSON.parse(chunk).result; let datetime = result.datetime_1; let week = result.week_4; mainWindow.webContents.send('datetime', { datetime, week }); }) }) request.end(); } // 监听渲染进程的时间获取请求 ipcMain.on('fetch-time', () => { fetchNetTime() })
第二步:修改渲染进程逻辑
- IPC监听只注册一次,不要放在重复执行的函数里
- 修正
setInterval的传参,定时器触发时给主进程发请求拉取最新时间
// 渲染进程代码修改 const { ipcRenderer } = require('electron') const timeText = document.querySelector('#timeText') // 只注册一次datetime事件监听 ipcRenderer.on('datetime', (event, arg) => { let datetime = arg.datetime; let week = arg.week; let year = datetime.substring(0, 4); let month = datetime.substring(5, 7); let day = datetime.substring(8, 10); let hour = datetime.substring(11, 13); // 原下标取值有误,第10位是空格,小时从第11位开始 let min = datetime.substring(14, 16); let sec = datetime.substring(17, 19); let weekday = ""; switch (week) { case 'Monday': weekday = '周一'; break; case 'Tuesday': weekday = '周二'; break; case 'Wednesday': weekday = '周三'; break; case 'Thursday': weekday = '周四'; break; case 'Friday': weekday = '周五'; break; case 'Saturday': weekday = '周六'; break; case 'Sunday': weekday = '周日'; break; } timeText.innerHTML = `${year}年${month}月${day}日 ${weekday} ${hour}:${min}:${sec}`; }) function fetchTimeFromMain() { // 给主进程发消息,请求拉取最新时间 ipcRenderer.send('fetch-time') } window.onload = () => { // 首次加载先请求一次 fetchTimeFromMain(); // 定时器传函数引用,不要加括号 setInterval(fetchTimeFromMain, 1000) }
优化提示
第三方接口每秒请求一次频率过高,可能会被接口限流,建议可以每30秒请求一次接口,拿到最新时间后本地用定时器做秒数累加,既减少接口请求次数,也能保证时间准确性。
内容的提问来源于stack exchange,提问作者linhk
相关产品推荐
相关产品推荐

