我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

在上一篇文章中,苏南大叔描述了在electron下载文件的时候,触发下载的几种形式。其中在文末留下了一个伏笔,那就是无法获知文件下载的进度,以及是否以及完成了下载。那么在本文中,苏南大叔就要进一步描述electron程序的文件下载过程中,如何监控文件下载进度。

苏南大叔:electron程序,如何监控文件下载进度,并显示进度条? - electron-download-processing
electron程序,如何监控文件下载进度,并显示进度条?(图6-1)

本文测试环境:macelectron@5.0.7

基本描述

本文中,在electron的渲染进程里面,苏南大叔放了几个文件下载的链接,是百度开发者工具的下载链接,用于测试。而且,在理解本文的内容之前,苏南大叔提示您,先读一下下面这篇前置文章:

will-download事件

electron的文件下载过程中,所有的控制层面代码,都是在一个will-download事件中进行编写的。所以,这个will-download事件,是解题的前提条件。

mainWindow.webContents.session.on('will-download', (event, item, webContents) => {
  //...
})

这里重点需要专注的就是item对象,关键信息都在这个item之中存储。这个item就可以理解为被下载的这个文件。值得注意的是:

  • 下载链接点击触发后,就会触发will-download
  • 然后会根据是否存在item.setSavePath()语句,来决定是否跳出保存对话框。
特别需要注意的是:保存对话框不阻塞进程!不阻塞进程!你选择目录的时候,没准都已经下载完了。这个操作很邪门。

是否出现保存对话框

如果有设置item.setSavePath(),就不会出现保存对话框,如果没有设置,就会出现对话框。这个理解上有些奇怪,不过确实就是这么触发的。

mainWindow.webContents.session.on('will-download', (event, item, webContents) => {
  const filePath = path.join(app.getPath('downloads'), item.getFilename());
  item.setSavePath(filePath);
  //...
})

上面的代码,就是把文件默认保存到了downloads这个系统目录下面了。具体的更多细节,可以参见下面的这篇文字:

注册item事件

对每个will-download里面的item,通过事件注册,进而就可以获得更多实时信息。比如:下载的进度百分比。那么item可以注册的事件都有那些呢?

苏南大叔:electron程序,如何监控文件下载进度,并显示进度条? - code-download-item-state
electron程序,如何监控文件下载进度,并显示进度条?(图6-2)

item.on('updated',()=>{})

这个itemupdated事件,是时刻更新触发的,获得进度就是主要在这里获取的。

item.on('updated', (event, state) => {
  if (state === 'progressing') {
    if (item.isPaused()) {
       
    }
    else{
      //这里是主战场
    }
  }
  else if (state === 'interrupted') {
  }
  else {
  }
});

从上述代码中,苏南大叔讲述了两个item事件:

  • 下载进行中,progressing,其中还有个暂停状态item.isPaused()
  • 下载被打断,interrupted

苏南大叔:electron程序,如何监控文件下载进度,并显示进度条? - code-item-done
electron程序,如何监控文件下载进度,并显示进度条?(图6-3)

计算进度

itemupdated事件中,苏南大叔选择一个合适的地方来获得合适的信息。对于本文的需求来说,主要推荐获取的item信息如下:

  • item.getFilename() 下载文件的名称
  • item.getSavePath() 下载文件的路径
  • item.getReceivedBytes() 下载文件已经下载的字节数
  • item.getTotalBytes() 下载文件的总字节数

已经下载的进度百分比:

(item.getReceivedBytes()/item.getTotalBytes()*100).toFixed(2)+"%"

item.once('done', () => {})

下载完成事件done中的state有三个分支,分别是:

  • completed,喜大普奔,下载完成。
  • cancelled,用户主动取消下载。
  • 其它,未知错误。
item.once('done', (event, state) => {
  if (state === 'completed') {
    //这里是主战场
  } else if (state=="cancelled") {
    //...
  }
  else{
    //...
  }
})

显示进度状态

主进程

进度状态的表现形式上,就多种多样了,因为上述代码都是在主进程中的,所以,主进程是近水楼台先得月的,可以在console中任意输出。

苏南大叔:electron程序,如何监控文件下载进度,并显示进度条? - electron-download-main
electron程序,如何监控文件下载进度,并显示进度条?(图6-4)

异常处理

  • 如果想要通知渲染进程中,这个就可能存在一个mainWindow不存在的异常。请注意处理。
if (!mainWindow.isDestroyed()) {
   //mainWindow正常存在
}

ipc通知渲染进程

主进程通知渲染进程的时候,也是需要这个mainWindow对象的。所以,一定要控制异常。

mainWindow.webContents.send('event-ipc', {
  name:item.getFilename(),
  receive:item.getReceivedBytes(),
  total:item.getTotalBytes(),
});

苏南大叔:electron程序,如何监控文件下载进度,并显示进度条? - electron-download-main-renderer
electron程序,如何监控文件下载进度,并显示进度条?(图6-5)

显示进度条

还可以在任务栏图标上面显示下载进度,这个效果是很高大上的。不过一样需要判断异常mainWindow。显示进度:

mainWindow.setProgressBar(item.getReceivedBytes() / item.getTotalBytes());

隐藏进度:

mainWindow.setProgressBar(-1) //不显示进度

苏南大叔:electron程序,如何监控文件下载进度,并显示进度条? - electron-download-icon
electron程序,如何监控文件下载进度,并显示进度条?(图6-6)

完整代码

主进程:

这是付费可看内容,收费5元。

渲染进程:

const {ipcRenderer} = require('electron')
ipcRenderer.on('down-process', (event,data) => {
    console.log(data);
});
ipcRenderer.on('down-cancle', (event,data) => {
    console.log("cancle");
});
ipcRenderer.on('down-done', (event,data) => {
    console.log("done");
});
ipcRenderer.on('down-fail', (event,data) => {
    console.log("fail");
});

相关链接

总结

本文中,苏南大叔主要讲述的话题是:electron程序,如何监控文件下载进度?至于最终的进度表现形式,大家还是根据自己的实际需求,进行处理比较好。

更多苏南大叔的electron程序,请点击苏南大叔的博客:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   electron