当前位置: 首页 > Web前端 > JavaScript

《学习笔记》child_process

时间:2023-03-26 23:33:20 JavaScript

child_processchild_process用于创建派生子进程。节点和派生的子进程建立stdin(标准输入)、stdout(标准输出)、stderr(标准错误)管道。child_process.spawn、child_process.fork、child_process.exec、child_process.execFile都返回ChildProcess实例。ChildProcess实例实现了EventEmitterAPI,可以在子进程实例上添加事件回调函数。进程可以通过事件消息系统相互通信。child_process.spawn启动子进程并执行命令。spawn的接口定义:spawn(command:string,args:ReadonlyArray,options:SpawnOptions):ChildProcesscommand,需要运行的命令args,运行命令的参数,是一个字符串数组options,配置项options.cwd子进程工作目录options.env环境变量,使用key,value配置环境变量等返回值ChildProcess,返回ChildProcess实例//exampleconst{spawn,spawnSync}=require('child_process')constpath=require('path')constcp=spawn('ls',['-a'],{cwd:path.resolve(__dirname,'../Movies')})cp.stdout.on('data',(data)=>{console.log(`subprocessoutput:'${data}`)})cp.on('exit',(code,signal)=>{console.log('subprocessexit:',`code${code}andsignal${signal}`)})输出:默认情况下,子进程的标准输入、标准输出和标准错误重定向到对应的subprocess.stdin、subprocess.stdout和subprocess。C上的标准错误hildProcess对象流。可以设置options.stdio:inherit,passedtoparentprocess,const{spawn,spawnSync}=require('child_process')constpath=require('path')constcp=spawn('ls',['-a'],{cwd:path.resolve(__dirname,'../Movies'),stdio:'inherit'})child_process.spawnSyncchild_process.spawn的同步版本。child_process.spawnSync返回对象。对象包含:pid(子进程pid)、stdout(标准输出)、stderr(标准错误)等。不同之处在于该函数在子进程完全关闭之前不会返回。const{spawnSync}=require('child_process')constpath=require('path')constobj=spawnSync('ls',['-a'],{cwd:path.resolve(__dirname,'../Movies')})console.log('pid',`${obj.pid}`)console.log('stdout',`${obj.stdout}`)child_process.exec创建一个生成的shell,然后可以执行生成的shell中的命令。exec实现函数重载。第二个参数可以是配置项或回调。如果第二个参数是配置项,那么第三个参数就是回调。const{exec}=require('child_process')constpath=require('path')exec('ls',(error,stdout,stderr)=>{if(error){console.error('error:',error);return;}console.log('stdout:'+stdout);console.log('stderr:'+stderr);})//第二个参数可以是配置项exec('ls-a',{cwd:path.resolve(__dirname,'../Movies'),},(error,stdout,stderr)=>{if(error){console.error('error:',error);返回;}控制台.log('stdout:'+stdout);console.log('stderr:'+stderr);})回调的三个参数分别是error实例(如果执行成功,error等于null),stdout标准输出,stderr标准错误。child_process.execSyncchild_process.exec的同步版本。child_process.execSync方法返回标准输出,除了该方法在子进程完全关闭之前不会返回。const{execSync}=require('child_process')constpath=require('path')conststdout=execSync('ls-a',{cwd:path.resolve(__dirname,'../Movies')})控制台.log('stdout:',`${stdout}`)child_process.exec和child_process.spawn之间的区别最大200kb的数据传输会缓存数据,进程关闭后的传输数据spawn适用于海量且长期的传输数据。exec适用于需要次数多、量少的情况。child_process.forkchild_process.fork,用于在子进程中运行模块。child_process.fork(modulePath[,args][,options])modulePath,子进程中需要运行的模块地址args,字符串参数列表options配置项execPath,用于创建子进程的可执行文件。我们可以通过配置该参数指定不同版本的node创建子进程。execArgv,传递给可执行文件的字符串参数列表。silent,子进程的标准输出,是否继承父进程。继承的默认值为false。如果设置为true直接管道到子进程的child.stdin、child.stdout等。stdio,用于配置父进程和子进程之间建立的管道//子进程的代码console.log('我是子进程')const{fork}=require('child_process')const{resolve}=require('path')//我是一个子进程fork(resolve(__dirname,'./cp.js'),{silent:false})//没有打印fork(resolve(__dirname,'./cp.js'),{silent:true})const{fork}=require('child_process')const{resolve}=require('path')constcp=fork(resolve(__dirname,'./cp.js'),{silent:true})cp.stdout.on('data',function(data){//stdout输出:我是子进程console.log('Outputinstdout:',`${data}`)})通过stdout属性,您可以获得子进程child_process.execFile的输出child_process.execFile不会创建派生shell。效率比exec高。child_process.execFile(file[,args][,options][,callback])文件,可以是可执行文件的名称或路径。const{execFile}=require('child_process')const{resolve}=require('path')execFile('node',[resolve(__dirname,'./cp.js')],(错误,stdout,stderr)=>{if(err){throwerr}console.log(`stdout:${stdout}`)})child_process.exec和child_process.execFileexec的区别是内部通过调用execFile实现的。而execFile内部是通过调用spawn来实现的。事件ChildProcess实例可以监听很多事件close,子进程的stdio流关闭时触发disconnect,父进程手动调用child.disconnect函数时触发error,发生错误时触发exit,message是当子进程退出时触发,子进程使用process.send函数在传递消息时触发const{fork}=require('child_process');constcp=fork('./cp.js')cp.on('close',(code,signal)=>{console.log('closeevent:',code,signal);})cp.on('disconnect',()=>{console.log('disconnectevent...');})cp.on('error',(code,signal)=>{console.log('errorevent:',code,signal);})cp.on('exit',(code,signal)=>{console.log('exitevent:',code,signal);})cp.on('message',(val)=>{console.log('messageevent:',val);})进程间通信创建子进程后,父进程与子进程之间会创建一个IPC通道,父子进程通过消息和发送进行通信。//父进程const{fork}=require('child_process');constcp=fork('./cp.js')cp.on('message',(msg)=>{console.log('message:'+JSON.stringify(msg))})//子进程process.send({msg:'我是子进程'})父进程也可以使用cp.send向子进程发送消息//父进程const{fork}=require('child_process');constcp=fork('./cp.js')cp.send({msg:'我是父进程'})参考Node.jsv16.8.0文档Node.jsChildProcesses:EverythingyouneedtoknowexecvsexecFilenodeJsNode.jsSpawnvs.ExecuteNodejs进阶:玩转转子进程(child_process)深入理解Node.js中的进程和线程Node.js进程模块学习指南玩转node子进程—child_process