ChildJob
ee-core:v2.11.0
# 介绍
ChildJob基于node.js子进程实现。触发任务时才会创建进程,任务执行完毕后,必须调用进程退出的方法:Ps.exit(), 否则进程无法退出,造成资源浪费。
优点:随用随取,用完释放,不过多占用电脑资源。
不足:频繁、大量创建任务时,会有启动进程的开销,业务略微延迟,此类业务推荐使用ChildPoolJob。
注意:node.js子进程中无法使用所有涉及electron的api(electron技术本身无法支持),相关业务请写在主进程
# 目录
./electron/jobs
# 使用方法
- 编写任务代码
# ./electron/jobs/example/timer.js
const Job = require('ee-core/jobs/baseJobClass');
const Loader = require('ee-core/loader');
const Log = require('ee-core/log');
const Ps = require('ee-core/ps');
const { childMessage } = require('ee-core/message');
// 引入 jobs 中的模块
const Hello = require('./hello');
// 引入 service 中的模块
const UserService = require('../../service/job/user');
/**
* example - TimerJob
* @class
*/
class TimerJob extends Job {
constructor(params) {
super();
this.params = params;
this.timer = undefined;
this.timeoutTimer = undefined;
this.number = 0;
this.countdown = 10; // 倒计时
}
/**
* handle()方法是必要的,且会被自动调用
*/
async handle () {
Log.info("[child-process] TimerJob params: ", this.params);
const { jobId } = this.params;
// 子进程中使用service
// 1. 需要重新实例化,因为子进程中没有ee的上下文
// 2. 确保引入的 service 中不能有electron 的 api或依赖, electron 不支持
const userService = new UserService();
userService.hello('job');
// 执行任务
this.doTimer(jobId);
}
/**
* 暂停任务运行
*/
async pause(jobId) {
Log.info("[child-process] Pause timerJob, jobId: ", jobId);
clearInterval(this.timer);
clearInterval(this.timeoutTimer);
}
/**
* 恢复任务运行
*/
async resume(jobId, pid) {
Log.info("[child-process] Resume timerJob, jobId: ", jobId, ", pid: ", pid);
this.doTimer(jobId);
}
/**
* 运行任务
*/
async doTimer(jobId) {
// 计时器模拟任务
let eventName = 'job-timer-progress-' + jobId;
this.timer = setInterval(() => {
Hello.welcome();
// 发送消息到主进程
childMessage.send(eventName, {jobId, number: this.number, end: false});
this.number++;
this.countdown--;
}, 1000);
// 用 setTimeout 模拟任务运行时长
this.timeoutTimer = setTimeout(() => {
// 关闭计时器模拟任务
clearInterval(this.timer);
// 任务结束,重置前端显示
childMessage.send(eventName, {jobId, number:0, pid:0, end: true});
// 如果是childJob任务,可以调用 Ps.exit() 方法,让进程主动退出,否则会常驻内存
// 如果是childPoolJob任务,常驻内存,等待下一个业务
if (Ps.isChildJob()) {
Ps.exit();
}
}, this.countdown * 1000)
}
}
TimerJob.toString = () => '[class TimerJob]';
module.exports = TimerJob;
- 触发任务
# ./electron/service/example.js
# 引入模块
const { ChildJob } = require('ee-core/jobs');
/**
* 示例服务(service层为单例)
* @class
*/
class ExampleService extends Service {
constructor(ctx) {
super(ctx);
// 在构造函数中初始化一些变量
this.myJob = new ChildJob();
this.taskForJob = {};
}
/**
* 执行任务
*/
doJob(jobId, action, event) {
let res = {};
let oneTask;
const channel = 'controller.framework.timerJobProgress';
if (action == 'create') {
// 执行任务及监听进度
let eventName = 'job-timer-progress-' + jobId;
const timerTask = this.myJob.exec('./jobs/example/timer', {jobId});
timerTask.emitter.on(eventName, (data) => {
Log.info('[main-process] timerTask, from TimerJob data:', data);
// 发送数据到渲染进程
event.sender.send(`${channel}`, data)
})
// 执行任务及监听进度 异步
// myjob.execPromise('./jobs/example/timer', {jobId}).then(task => {
// task.emitter.on(eventName, (data) => {
// Log.info('[main-process] timerTask, from TimerJob data:', data);
// // 发送数据到渲染进程
// event.sender.send(`${channel}`, data)
// })
// });
res.pid = timerTask.pid;
this.taskForJob[jobId] = timerTask;
}
if (action == 'close') {
oneTask = this.taskForJob[jobId];
// 结束job进程
oneTask.kill();
event.sender.send(`${channel}`, {jobId, number:0, pid:0});
}
if (action == 'pause') {
oneTask = this.taskForJob[jobId];
// 调用job 中的方法
oneTask.callFunc('./jobs/example/timer', 'pause', jobId);
}
if (action == 'resume') {
oneTask = this.taskForJob[jobId];
// 调用job 中的方法
oneTask.callFunc('./jobs/example/timer', 'resume', jobId, oneTask.pid);
}
return res;
}
}
ExampleService.toString = () => '[class ExampleService]';
module.exports = ExampleService;
上次更新: 2025/03/27, 02:12:08