在child_process域和错误的冒泡和捕获实践【Note.js】

简介: 在child_process域和错误的冒泡和捕获实践【Note.js】

child_process

child_进程模块提供派生子进程的功能。它与popen(3)相似但不相同。此函数主要由[child_process.spown()]函数提供:

const { spawn } = require('child_process');
const ls = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', (data) => {
  console.log(`输出:${data}`);
});

ls.stderr.on('data', (data) => {
  console.log(`错误:${data}`);
});

ls.on('close', (code) => {
  console.log(`子进程退出码:${code}`);
});
const { exec } = require('child_process');
exec('my.bat', (err, stdout, stderr) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(stdout);
});

// 文件名带有空格的脚本:
const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true });
// 或:
exec('"my script.cmd" a b', (err, stdout, stderr) => {
  // ...
});

child_进程模块还提供一些其他同步和异步可选功能。每个函数都是基于[child_process.spawn()]或[child_process.spawnSync()]实现的。
[child_process.exec()]:派生一个shell并在该shell上运行命令。完成后,stdout和stderr将传递给回调函数。

const { spawn } = require('child_process');
const grep = spawn('grep', ['ssh']);

grep.on('close', (code, signal) => {
  console.log(`子进程收到信号 ${signal} 而终止`);
});

// 发送 SIGHUP 到进程
grep.kill('SIGHUP');

[child_process.execFile()]:类似于[child_procedure.exec()],但命令是直接派生的,而不首先派生shell。
[child_process.f分叉()]:派生一个新的NodeJs进程,并通过建立IPC通信通道调用指定的模块,这允许父进程和子进程相互发送信息。
[child_process.execSync()]:[child_procedure.exec()]的同步函数阻止节点J的事件循环。
[child_process.execFileSync()]:[child_cess.execFile()]的同步函数阻止节点J的事件循环。

options.detached

在Windows上,设置选项如果分离为true,则子进程可以在父进程退出后继续运行。子进程有自己的控制台窗口。一旦启用了子进程,就不能禁用它。
在非Windows平台上,如果选项if detached设置为true,则子进程将成为新进程组和会话的领导者。请注意,子进程可以在父进程退出后继续运行,无论它们是否分离。详见setsid(2)。

const fs = require('fs');
const { spawn } = require('child_process');
const out = fs.openSync('./out.log', 'a');
const err = fs.openSync('./out.log', 'a');

const subprocess = spawn('prg', [], {
  detached: true,
  stdio: [ 'ignore', out, err ]
});

subprocess.unref();

默认情况下,父进程将等待分离的子进程退出。为了防止父进程等待给定的子进程,可以使用子进程Unref()方法。这将导致父进程的事件循环排除子进程的引用计数,使父进程独立于子进程退出,除非在子进程和父进程之间建立了IPC通道。
使用分离选项启动长时间运行的进程时,除非提供了未连接到父进程的stdio配置,否则父进程退出后,该进程将不会在后台继续运行。如果继承了父进程的stdio,则子进程将保持与控制终端的连接。
例如,对于长时间运行的进程,为了忽略父进程的终止,父进程的stdio文件描述符被分离并忽略:

const { spawn } = require('child_process');

const subprocess = spawn(process.argv[0], ['child_program.js'], {
  detached: true,
  stdio: 'ignore'
});

subprocess.unref();

如果未传递信号,[ChildProcess]对象可能会触发['error']事件。向已退出的子进程发送信号不是错误,但可能会产生不可预测的后果。特别是,如果一个进程的PID被重新分配给另一个进程,则该信号将被发送给该进程,这可能会导致意外的结果。
注意,当函数被称为kill时,发送给子进程的信号实际上可能不会终止该进程。

'use strict';
const { spawn } = require('child_process');

const subprocess = spawn(
  'sh',
  [
    '-c',
    `node -e "setInterval(() => {
      console.log(process.pid, 'is alive')
    }, 500);"`
  ], {
    stdio: ['inherit', 'inherit', 'inherit']
  }
);

setTimeout(() => {
  subprocess.kill(); // 不会终止 shell 中的 node 进程
}, 2000);

一旦套接字被传递给子进程,父进程就无法再跟踪套接字何时被销毁。若要显示此属性,连接属性将变为空。发生这种情况时,不建议使用。最大连接数。
建议子进程中的任何消息处理程序都应验证套接字是否存在,因为连接在发送到子进程期间可能会关闭。

cipher.update

用数据更新密码。如果给定inputEncoding参数,其值必须为“utf8”、“ascii”或“latin1”,并且数据参数是使用指定编码的字符串。如果未给定inputEncoding参数,则数据必须为Buffer、TypedArray或DataView。如果数据是Buffer、TypedArray或DataView,则忽略inputEncoding。
OutputEncoding指定加密数据的输出格式,可以是“latin1”、“base64”或“hex”。如果指定了outputEncoding,则返回具有指定编码的字符串。如果未提供outputEncoding,将返回Buffer。
密码。update()方法可以用新数据多次调用,直到调用密码Final()。['cipher.final()'][]调用密码。update()。final()将抛出错误。

const crypto = require('crypto');
const decipher = crypto.createDecipher('aes192', 'a password');

let decrypted = '';
decipher.on('readable', () => {
  const data = decipher.read();
  if (data)
    decrypted += data.toString('utf8');
});
decipher.on('end', () => {
  console.log(decrypted);
  // Prints: some clear text data
});

const encrypted =
    'ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504';
decipher.write(encrypted, 'hex');
decipher.end();
const crypto = require('crypto');
const fs = require('fs');
const decipher = crypto.createDecipher('aes192', 'a password');

const input = fs.createReadStream('test.enc');
const output = fs.createWriteStream('test.js');

input.pipe(decipher).pipe(output);

返回所有剩余的解密内容。如果outputEncoding参数是“latin1”、“ascii”或“utf8”之一,则返回字符串。如果未提供输出编码,则返回Buffer。
一旦解密了final()方法,decipher对象就不能再用于解密数据。正在尝试调用解密。final()多次导致抛出错误。

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

// Generate Alice's keys...
const alice = crypto.createDiffieHellman(2048);
const aliceKey = alice.generateKeys();

// Generate Bob's keys...
const bob = crypto.createDiffieHellman(alice.getPrime(), alice.getGenerator());
const bobKey = bob.generateKeys();

// Exchange and generate the secret...
const aliceSecret = alice.computeSecret(bobKey);
const bobSecret = bob.computeSecret(aliceKey);

// OK
assert.strictEqual(aliceSecret.toString('hex'), bobSecret.toString('hex'));

错误的冒泡和捕获

节点。Js支持几种机制来冒泡和处理应用程序运行时发生的错误。如何报告和处理这些错误完全取决于错误的类型和调用的API的样式。
所有JavaScript错误都将被视为异常。将立即生成异常,并使用标准JavaScript抛出机制抛出错误。这些都是使用JavaScript语言提供的try/catch语句处理的。

try {
  const m = 1;
  const n = m + z;
} catch (err) {
  // 在这里处理错误。
}

任何使用JavaScript的抛出机制都会导致异常。异常必须用try/catch处理,否则Node.js进程将立即退出。
除了少数例外,同步API(任何不接受回调函数的阻塞方法,如[fs.readFileSync])将使用throw来报告错误。
异步API中的错误可以通过几种方式报告:
大多数异步方法都接受回调函数,该函数接受Error对象作为第一个参数。如果第一个参数不是null,而是一个Error实例,则表示发生了错误,应进行处理。

相关文章
|
1月前
|
数据可视化 JavaScript API
使用D3.js进行数据可视化的探索与实践
【6月更文挑战第2天】本文探讨了D3.js在数据可视化中的应用,介绍了D3.js作为JavaScript库的特性,包括数据驱动、灵活性和兼容性。实践中,涉及数据准备、创建SVG容器、数据绑定与绘制、交互与动画以及样式美化。D3.js使开发人员能高效创建动态、交互式图表,适用于多平台和设备。未来,随着数据可视化技术进步,D3.js的应用前景广阔。
|
17天前
|
JavaScript 前端开发 Shell
深入Node.js的进程与子进程:从文档到实践
深入Node.js的进程与子进程:从文档到实践
|
1月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp小程序的面向智慧教育的实习实践系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp小程序的面向智慧教育的实习实践系统附带文章源码部署视频讲解等
13 0
|
1月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的实践项目管理系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的实践项目管理系统附带文章和源代码部署视频讲解等
12 0
|
2月前
|
JavaScript Java 测试技术
返家乡”高校暑期社会实践微信小程序+springboot+vue.js附带文章和源代码设计说明文档ppt
返家乡”高校暑期社会实践微信小程序+springboot+vue.js附带文章和源代码设计说明文档ppt
23 0
|
2月前
|
JavaScript 前端开发 测试技术
【JavaScript技术专栏】JavaScript模块化开发实践
【4月更文挑战第30天】JavaScript模块化开发缓解了大规模应用的复杂性,通过拆分为独立模块提升代码可维护性、可读性和可测试性。CommonJS在Node.js中用于服务器,而AMD(RequireJS)适合浏览器的异步加载。ES6模块结合两者优点,提供原生支持。实践时遵循单一职责、命名规范和依赖管理等原则,借助Webpack、RequireJS等工具提升效率。模块化是现代JavaScript不可或缺的一部分,促进团队协作和代码复用。
|
2月前
|
消息中间件 监控 JavaScript
Node.js中的微服务架构:构建与实践
【4月更文挑战第30天】本文探讨了在Node.js中构建微服务的实践,包括定义服务边界、选择框架(如Express、Koa或NestJS)、设计RESTful API、实现服务间通信(HTTP、gRPC、消息队列)、错误处理、服务发现与负载均衡,以及监控和日志记录。微服务架构能提升应用的可伸缩性、灵活性和可维护性。
|
7月前
|
JavaScript 索引
JS中数组的增删改查操作实践总结
JS中数组的增删改查操作实践总结
59 0
|
2月前
|
数据采集 JavaScript 前端开发
利用axios库在Node.js中进行代理请求的实践
利用axios库在Node.js中进行代理请求的实践
|
2月前
|
Web App开发 JavaScript 前端开发
深入浅出:Node.js 在后端开发中的应用与实践
【2月更文挑战第13天】本文旨在探讨Node.js这一流行的后端技术如何在现代Web开发中被应用以及它背后的核心优势。通过深入分析Node.js的非阻塞I/O模型、事件驱动机制和单线程特性,我们将揭示其在处理高并发场景下的高效性能。同时,结合实际开发案例,本文将展示如何利用Node.js构建高性能、可扩展的后端服务,以及在实际项目中遇到的挑战和解决方案。此外,我们还将讨论Node.js生态系统中的重要工具和库,如Express.js、Koa.js等,它们如何帮助开发者快速搭建和部署应用。通过本文的探讨,读者将获得对Node.js在后端开发中应用的深入理解,以及如何有效利用这一技术来提升开发效率
246 2