美文网首页
Node子进程进阶

Node子进程进阶

作者: Devildi已被占用 | 来源:发表于2018-12-05 16:31 被阅读0次

    最近在做12306爬虫,刚好遇到了Node子进程的应用场景,不总结不快:

    const { spawn, exec, execFile ,fork } = require('child_process');
    

    Node的child_process模块提供了衍生子进程的功能,通常子进程开启后,会与父进程建立 stdinstdoutstderr 的管道。如上代码所示,child_process模块暴露了4个方法,其中spawn为“根本大法”,其余的3个均在其基础上衍生而来,而每个方法都有同步和异步两个版本,本文主要以异步方法为主,因为结合Node单线程和12306爬虫这个web应用来说,谈论异步场景更为合适。

    spawn(command[, args][, options])

    #运行 ls -lh /usr,并捕获 stdout、stderr、以及退出码(取自Node官网)
    const { spawn } = require('child_process');
    const ls = spawn('ls', ['-lh', '/usr']);
    
    ls.stdout.on('data', (data) => {
      console.log(`stdout: ${data}`);
    });
    
    ls.stderr.on('data', (data) => {
      console.log(`stderr: ${data}`);
    });
    
    ls.on('close', (code) => {
      console.log(`子进程退出码:${code}`);
    });
    

    exec(command[, options][, callback])

    此方法生成一个 shell 并在 shell 中执行 command

    const { exec } = require('child_process');
    exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => {
      if (error) {
        console.error(`执行出错: ${error}`);
        return;
      }
      console.log(`stdout: ${stdout}`);
      console.log(`stderr: ${stderr}`);
    });
    

    execFile(file[, args][, options][, callback])

    本方法与exec()类似,只是不衍生 shell。 file脚本文件会被直接衍生为一个新进程,这使得它比 child_process.exec() 更高效

    const { execFile } = require('child_process');
    const child = execFile('node', ['--version'], (error, stdout, stderr) => {
      if (error) {
        throw error;
      }
      console.log(stdout);
    });
    

    可以使用util.promisify()进行Promise化:

    const util = require('util');
    const execFile = util.promisify(require('child_process').execFile);
    async function getVersion() {
      const { stdout } = await execFile('node', ['--version']);
      console.log(stdout);
    }
    getVersion();
    

    fork(modulePath[, args][, options])

    fork()方法用于专门衍生新的 Node.js 进程,衍生的 Node.js 子进程与两者之间建立的 IPC 通信信道的异常是独立于父进程的。 每个进程都有自己的内存,使用自己的 V8 实例。 由于需要额外的资源分配,因此不建议衍生大量的 Node.js 进程。spawn ()方法的一种特殊情况。

    总结

    spawn(), exec(), execFile() ,fork()都遵循 Node.js 惯用的异步编程模式。每个方法都返回 ChildProcess实例。这些对象都实现了 EventEmitter接口,允许父进程注册监听器函数,在子进程生命周期期间,当特定的事件(close/disconnect/error/exit/message)发生时会调用这些函数。
    其中,exec()execFile() 可以额外指定 callback 函数,当子进程结束时会被调用。

    相关文章

      网友评论

          本文标题:Node子进程进阶

          本文链接:https://www.haomeiwen.com/subject/pyjmcqtx.html