【问题标题】:Should I use worker or child processes to run my function?我应该使用工作进程还是子进程来运行我的函数?
【发布时间】:2021-11-30 17:54:30
【问题描述】:
我有两个文件,main.js 和 job.js。当在 main.js 中单击一个按钮时,我希望在 job.js 中运行一个新的、单独的函数进程。
这个过程的作用是启动一个新的 puppeteer 浏览器实例。当点击停止按钮时,这个进程应该被 pid 杀死。 (为此我们使用process.kill(child.pid)?)
那么我想使用工作进程还是子进程,如果这两个进程中的任何一个,我将如何实现它以便它运行这个函数?
重要提示:每次点击开始按钮时,我希望启动一个运行该功能的新进程,因此可以杀死具有该pid的特定进程。
【问题讨论】:
标签:
javascript
node.js
electron
puppeteer
【解决方案1】:
我建议您为child_process 模块使用包装器模块。 execa 模块的用法示例。
Main.js
const { execa } = require('execa')
// function for spawning a process with cancel handle!.
async function spawnSubprocess(command, args, cb) {
let subprocess = execa(command, args);
// create a cancel function for later usage!.
function cancel() {
if(subprocess) {
subprocess.kill('SIGTERM', {
// wait for it to terminate before killing it.
forceKillAfterTimeout: 1500
});
// set to null so it won't be killed mutliple times.
subprocess = null
}
}
// add the event listener to subprocess when it's done!
// Can be used for logging or for correctly awaiting a process
// termination before proceeding.
subprocess.then(() => {
subprocess = null
cb()
})
.catch(err => {
subprocess = null
cb(err)
})
// return the cancel handler !.
return cancel
}
// reference to the last cancel. It has to be accessible in
// onClickHandler ofc!.
var processCancel = null
// call this function on click.
// keep the processCancel in scope!
function onClickHandler() {
// first, check if a process is already running
if(typeof processCancel === 'function') {
console.log('Process already running. Calling cancel!')
// the process is not directly terminated. You amy have
// 2 seconds where multiple instances are running but that's not a big deal i guess.
processCancel()
}
// spawn the new process !
// adjust the path to job.js ofc!.
processCancel = spawnSubprocess('node', ['job.js'], (err) => {
// on done callback!. Log some information!.
if(err) {
console.error('Process error ', err)
} else {
console.log('process stopped / DONE')
}
processCancel = null
})
}
这应该让您了解如何实现它。我建议使用child_process 或任何包装模块。 ^^