electron的setInterval问题!!!

大唐雄風
  • 3
新手上路,请多包涵

我尝试编写electron应用程序时遇到了一个难题,以下是对该问题的详细描述:
我想在electron渲染进程的页面上加载一个时钟,就像我们的系统时间一样,它将每秒刷新一次,60秒是一分钟,以此类推,但是我没使用系统时间,而是使用当前的北京时间 API,此API接口返回的json数据是当前的北京时间戳,我在主进程main.js中编写了一套异步请求函数,以获取此API传递的数据。下面是main.js异步获取时间的主要流程代码:

const request = net.request('http://api.k780.com:88/?app=life.time&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json')

  request.on('response', (response) => {
    console.log(response.statusCode);
    console.log(response.headers);

    response.on('data', (chunk) => {
      let result = JSON.parse(chunk).result;
      let datetime = result.datetime_1;
      let week = result.week_4;
      console.log(datetime, week)
      mainWindow.webContents.send('datetime', { datetime, week });
    })

    response.on('end', () => {
      console.log('end');

    })

  })
  request.end();

主进程显示的控制台信息如下:

200
{
  server: 'nginx',
  date: 'Thu, 06 May 2021 01:38:00 GMT',
  'content-type': 'application/json; charset=utf-8;',
  'transfer-encoding': 'chunked',
  connection: 'keep-alive',
  'access-control-allow-origin': '*'
}
2021-05-06 09:38:01 Thursday
end

然后,在请求此API之后,响应了当前北京时间的时间戳,主进程获取此时间戳后,通过webContents.send发送到我的渲染进程。以下是主流程发送给渲染进程的代码:

mainWindow.webContents.send('datetime', { datetime, week });

渲染进程通过ipcRenderer.on获取主进程发送过来的时间数据,然后格式化该时间戳并将其输出到我的渲染进程页面。我将此其编写为函数,代码如下所示:

function getNetTime() {
    //获取主进程传来的日期时间
    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(10, 13); //获取小时
        let min = datetime.substring(14, 16); //获取分钟
        let sec = datetime.substring(17, 19); //获取秒钟
        let weekday = ""; //获取中文周几
        const timeText = document.querySelector('#timeText') //获取时间文字dom
        console.log(datetime);
        // console.log(week);
        // console.log(year,month,day,hour,min);
        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}`;
    });

}

现在遇到的问题是,尽管当前时间可以在渲染进程的页面上正常显示,但是却无法自动刷新。我想将其设置为通过setTimeout或setInterval每隔1000毫秒刷新一次,这等效于1秒钟一步的时钟,但是没有任何效果,当前时间只能在重新打开程序时显示,并且无法自动刷新。以下是setInterval的代码:

window.onload = () => {
    getNetTime();
    setInterval(getNetTime(),1000)
    
}

以上就是我遇到的问题,我也是初学electron的小白,希望各位大佬可以告诉一下怎么解决这个问题,谢谢!

回复
阅读 272
3 个回答

你这是javascript的问题,你放在setInterval的逻辑因该是派发事件的事件的
比如

mainWindow.webContents.send('datetime', { datetime, week });

而监听事件的逻辑只用在onload执行一次

参考代码:

主线程
const fetchDate = () => {
  return new Promise((resolve, reject) => {
    const request = net.request(
      'http://api.k780.com:88/?app=life.time&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json'
    )

    request.on('response', (response) => {
      console.log(response.statusCode)
      console.log(response.headers)

      response.on('data', (chunk) => {
        let result = JSON.parse(chunk).result
        let datetime = result.datetime_1
        let week = result.week_4
        console.log(datetime, week)
        resolve({ datetime, week })
      })

      response.on('end', () => {
        console.log('end')
      })
    })
    request.end()
  })
}

setInterval(() => {
  fetchDate().then((date) => {
    mainWindow.webContents.send('datetime', date)
  })
}, 1000)
子线程
window.onload = () => {
  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(10, 13) //获取小时
    let min = datetime.substring(14, 16) //获取分钟
    let sec = datetime.substring(17, 19) //获取秒钟
    let weekday = '' //获取中文周几
    const timeText = document.querySelector('#timeText') //获取时间文字dom
    console.log(datetime)
    // console.log(week);
    // console.log(year,month,day,hour,min);
    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}`
  })
}

我看你只写了定时执行的渲染函数,没写定时去请求接口的函数
你可以只定时去请求接口,并且发送给你的渲染进程,类似事件驱动的,渲染函数就不用定时执行了

setInterval(getNetTime,1000)

而不是

setInterval(getNetTime(),1000)
你知道吗?

宣传栏