深入Node.js的进程与子进程:从文档到实践

2019/04/10 10:10
阅读数 19

<section id="nice" data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="font-size: 16px; color: black; padding: 10px; line-height: 1.6; word-spacing: 0px; letter-spacing: 0px; word-break: break-word; word-wrap: break-word; text-align: left; font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, 'PingFang SC', Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;"><figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px;"><img src="https://tva1.sinaimg.cn/large/006tNbRwly1gb33drjdzqj318g0qc3zq.jpg" alt style="display: block; margin: 0 auto; width: 100%;"></figure> <blockquote data-tool="mdnice编辑器" style="display: block; font-size: 0.9em; overflow: auto; overflow-scrolling: touch; border-left: 3px solid rgba(0, 0, 0, 0.4); background: rgba(0, 0, 0, 0.05); padding-top: 10px; padding-bottom: 10px; border-left-color: rgb(221, 221, 221); margin-top: 1.2em; margin-bottom: 1.2em; padding-right: 1em; padding-left: 1em; border-left-width: 4px; color: rgb(119, 119, 119); quotes: none;"> <p style="padding-top: 8px; padding-bottom: 8px; box-sizing: border-box; margin-bottom: 16px; text-align: start; white-space: normal; text-size-adjust: auto; margin: 0px; font-size: 15px; font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; color: rgb(119, 119, 119); line-height: 1.75em;"><strong style="font-weight: bold; color: black;">欢迎关注Github仓库,这是一个自2018年起持续更新的前端&amp;算法开源博客。目前已有node学习、js面试笔记、css3动画设计、webpack4系列教程、设计模式、剑指offer·js版等多个系列。</strong></p> <p style="padding-top: 8px; padding-bottom: 8px; box-sizing: border-box; margin-bottom: 16px; text-align: start; white-space: normal; text-size-adjust: auto; margin: 0px; font-size: 15px; font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; color: rgb(119, 119, 119); line-height: 1.75em;"><strong style="font-weight: bold; color: black;">仓库地址:<a href="https://github.com/dongyuanxin/blog" style="text-decoration: none; word-wrap: break-word; font-weight: bold; color: rgb(239, 112, 96); border-bottom: 1px solid rgb(239, 112, 96);">https://github.com/dongyuanxin/blog</a></strong></p> </blockquote> <h1 data-tool="mdnice编辑器" style="font-weight: bold; color: black; font-size: 28px; margin-top: -0.46em; margin-bottom: 0.1em; border-bottom: 2px solid rgb(198, 196, 196); box-sizing: border-box;"><span style="padding-top: 5px; padding-bottom: 5px; color: rgb(160, 160, 160); font-size: 13px; line-height: 2; box-sizing: border-box;">进程:process模块</span></h1> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">process 模块是 nodejs 提供给开发者用来和当前进程交互的工具,它的提供了很多实用的 API。从文档出发,管中窥豹,进一步认识和学习 process 模块:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; list-style-type: disc;"> <li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">如何处理命令参数?</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">如何处理工作目录?</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">如何处理异常?</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">如何处理进程退出?</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">process 的标准流对象</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">深入理解 process.nextTick</section></li></ul> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; margin: 10px auto; height: 40px; background-color: rgb(251, 251, 251); border-bottom: 1px solid rgb(246, 246, 246); overflow: hidden; box-sizing: border-box;"><span style="margin-left: -10px; display: inline-block; width: auto; height: 40px; background-color: rgb(33, 33, 34); border-bottom-right-radius: 100px; color: rgb(255, 255, 255); padding-right: 30px; padding-left: 30px; line-height: 40px; font-size: 16px;">如何处理命令参数?</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">命令行参数指的是 2 个方面:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; list-style-type: disc;"> <li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">传给 node 的参数。例如 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">node --harmony script.js --version</code> 中,<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">--harmony</code> 就是传给 node 的参数</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">传给进程的参数。例如 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">node script.js --version --help</code> 中,<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">--version --help</code> 就是传给进程的参数</section></li></ul> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">它们分别通过 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">process.argv</code> 和 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">process.execArgv</code> 来获得。</p> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; margin: 10px auto; height: 40px; background-color: rgb(251, 251, 251); border-bottom: 1px solid rgb(246, 246, 246); overflow: hidden; box-sizing: border-box;"><span style="margin-left: -10px; display: inline-block; width: auto; height: 40px; background-color: rgb(33, 33, 34); border-bottom-right-radius: 100px; color: rgb(255, 255, 255); padding-right: 30px; padding-left: 30px; line-height: 40px; font-size: 16px;">如何处理工作目录?</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">通过<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">process.cwd()</code>可以获取当前的工作目录。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">通过<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">process.chdir(directory)</code>可以切换当前的工作目录,失败后会抛出异常。实践如下:</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #333; background: #f8f8f8; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">function</span> <span class="hljs-title" style="color: #900; font-weight: bold; line-height: 26px;">safeChdir</span>(<span class="hljs-params" style="line-height: 26px;">dir</span>) </span>{ <span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">try</span> { process.chdir(dir); <span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">return</span> <span class="hljs-literal" style="color: #008080; line-height: 26px;">true</span>; } <span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">catch</span> (error) { <span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">return</span> <span class="hljs-literal" style="color: #008080; line-height: 26px;">false</span>; } } </code></pre> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; margin: 10px auto; height: 40px; background-color: rgb(251, 251, 251); border-bottom: 1px solid rgb(246, 246, 246); overflow: hidden; box-sizing: border-box;"><span style="margin-left: -10px; display: inline-block; width: auto; height: 40px; background-color: rgb(33, 33, 34); border-bottom-right-radius: 100px; color: rgb(255, 255, 255); padding-right: 30px; padding-left: 30px; line-height: 40px; font-size: 16px;">如何处理异常?</span></h2> <h3 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 20px; margin: 20px auto 5px; border-top: 1px solid rgb(221, 221, 221); box-sizing: border-box;"><span style="margin-top: -1px; padding-top: 6px; padding-right: 5px; padding-left: 5px; font-size: 17px; border-top: 2px solid rgb(33, 33, 34); display: inline-block; line-height: 1.1;">uncaughtException 事件</span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">Nodejs 可以通过 try-catch 来捕获异常。如果异常未捕获,则会一直从底向事件循环冒泡。如是冒泡到事件循环的异常没被处理,那么就会导致当前进程异常退出。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">根据文档,可以通过监听 process 的 uncaughtException 事件,来处理未捕获的异常:</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #333; background: #f8f8f8; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">process.on(<span class="hljs-string" style="color: #d14; line-height: 26px;">"uncaughtException"</span>, (err, origin) =&gt; { <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(err.message); });

<span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">const</span> a = <span class="hljs-number" style="color: #008080; line-height: 26px;">1</span> / b; <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(<span class="hljs-string" style="color: #d14; line-height: 26px;">"abc"</span>); <span class="hljs-comment" style="color: #998; font-style: italic; line-height: 26px;">// 不会执行</span> </code></pre>

<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">上面的代码,控制台的输出是:<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">b is not defined</code>。捕获了错误信息,并且进程以<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">0</code>退出。开发者可以在 uncaughtException 事件中,清除一些已经分配的资源(文件描述符、句柄等),不推荐在其中重启进程。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 20px; margin: 20px auto 5px; border-top: 1px solid rgb(221, 221, 221); box-sizing: border-box;"><span style="margin-top: -1px; padding-top: 6px; padding-right: 5px; padding-left: 5px; font-size: 17px; border-top: 2px solid rgb(33, 33, 34); display: inline-block; line-height: 1.1;">unhandledRejection 事件</span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">如果一个 Promise 回调的异常没有被<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">.catch()</code>捕获,那么就会触发 process 的 unhandledRejection 事件:</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #333; background: #f8f8f8; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">process.on(<span class="hljs-string" style="color: #d14; line-height: 26px;">"unhandledRejection"</span>, (err, promise) =&gt; { <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(err.message); });

<span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">Promise</span>.reject(<span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">new</span> <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">Error</span>(<span class="hljs-string" style="color: #d14; line-height: 26px;">"错误信息"</span>)); <span class="hljs-comment" style="color: #998; font-style: italic; line-height: 26px;">// 未被catch捕获的异常,交由unhandledRejection事件处理</span> </code></pre>

<h3 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 20px; margin: 20px auto 5px; border-top: 1px solid rgb(221, 221, 221); box-sizing: border-box;"><span style="margin-top: -1px; padding-top: 6px; padding-right: 5px; padding-left: 5px; font-size: 17px; border-top: 2px solid rgb(33, 33, 34); display: inline-block; line-height: 1.1;">warning 事件</span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">告警不是 Node.js 和 Javascript 错误处理流程的正式组成部分。 一旦探测到可能导致应用性能问题,缺陷或安全隐患相关的代码实践,Node.js 就可发出告警。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">比如前一段代码中,如果出现未被捕获的 promise 回调的异常,那么就会触发 warning 事件。</p> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; margin: 10px auto; height: 40px; background-color: rgb(251, 251, 251); border-bottom: 1px solid rgb(246, 246, 246); overflow: hidden; box-sizing: border-box;"><span style="margin-left: -10px; display: inline-block; width: auto; height: 40px; background-color: rgb(33, 33, 34); border-bottom-right-radius: 100px; color: rgb(255, 255, 255); padding-right: 30px; padding-left: 30px; line-height: 40px; font-size: 16px;">如何处理进程退出?</span></h2> <h3 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 20px; margin: 20px auto 5px; border-top: 1px solid rgb(221, 221, 221); box-sizing: border-box;"><span style="margin-top: -1px; padding-top: 6px; padding-right: 5px; padding-left: 5px; font-size: 17px; border-top: 2px solid rgb(33, 33, 34); display: inline-block; line-height: 1.1;">process.exit() vs process.exitCode</span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">一个 nodejs 进程,可以通过 process.exit() 来指定退出代码,直接退出。<strong style="font-weight: bold; color: black;">不推荐直接使用 process.exit()</strong>,这会导致事件循环中的任务直接不被处理,以及可能导致数据的截断和丢失(例如 stdout 的写入)。</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #333; background: #f8f8f8; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">setTimeout(<span class="hljs-function" style="line-height: 26px;"><span class="hljs-params" style="line-height: 26px;">()</span> =&gt;</span> { <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(<span class="hljs-string" style="color: #d14; line-height: 26px;">"我不会执行"</span>); });

process.exit(<span class="hljs-number" style="color: #008080; line-height: 26px;">0</span>); </code></pre>

<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;"><strong style="font-weight: bold; color: black;">正确安全的处理是</strong>,设置 process.exitCode,并允许进程自然退出。</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #333; background: #f8f8f8; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">setTimeout(<span class="hljs-function" style="line-height: 26px;"><span class="hljs-params" style="line-height: 26px;">()</span> =&gt;</span> { <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(<span class="hljs-string" style="color: #d14; line-height: 26px;">"我不会执行"</span>); });

process.exitCode = <span class="hljs-number" style="color: #008080; line-height: 26px;">1</span>; </code></pre>

<h3 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 20px; margin: 20px auto 5px; border-top: 1px solid rgb(221, 221, 221); box-sizing: border-box;"><span style="margin-top: -1px; padding-top: 6px; padding-right: 5px; padding-left: 5px; font-size: 17px; border-top: 2px solid rgb(33, 33, 34); display: inline-block; line-height: 1.1;">beforeExit 事件</span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">用于处理进程退出的事件有:beforeExit 事件 和 exit 事件。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">当 Node.js 清空其事件循环并且没有其他工作要安排时,会触发 beforeExit 事件。例如在退出前需要一些异步操作,那么可以写在 beforeExit 事件中:</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #333; background: #f8f8f8; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">let</span> hasSend = <span class="hljs-literal" style="color: #008080; line-height: 26px;">false</span>; process.on(<span class="hljs-string" style="color: #d14; line-height: 26px;">"beforeExit"</span>, () =&gt; { <span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">if</span> (hasSend) <span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">return</span>; <span class="hljs-comment" style="color: #998; font-style: italic; line-height: 26px;">// 避免死循环</span>

setTimeout(<span class="hljs-function" style="line-height: 26px;"><span class="hljs-params" style="line-height: 26px;">()</span> =&gt;</span> {
    <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(<span class="hljs-string" style="color: #d14; line-height: 26px;">"mock send data to serve"</span>);
    hasSend = <span class="hljs-literal" style="color: #008080; line-height: 26px;">true</span>;
}, <span class="hljs-number" style="color: #008080; line-height: 26px;">500</span>);

});

<span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(<span class="hljs-string" style="color: #d14; line-height: 26px;">"......."</span>); <span class="hljs-comment" style="color: #998; font-style: italic; line-height: 26px;">// 输出:</span> <span class="hljs-comment" style="color: #998; font-style: italic; line-height: 26px;">// .......</span> <span class="hljs-comment" style="color: #998; font-style: italic; line-height: 26px;">// mock send data to serve</span> </code></pre>

<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">注意:在 beforeExit 事件中如果是异步任务,那么又会被添加到任务队列。此时,任务队列完成所有任务后,又回触发 beforeExit 事件。因此,不处理的话,<strong style="font-weight: bold; color: black;">可能出现死循环的情况</strong>。如果是显式调用 exit(),那么不会触发此事件。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 20px; margin: 20px auto 5px; border-top: 1px solid rgb(221, 221, 221); box-sizing: border-box;"><span style="margin-top: -1px; padding-top: 6px; padding-right: 5px; padding-left: 5px; font-size: 17px; border-top: 2px solid rgb(33, 33, 34); display: inline-block; line-height: 1.1;">exit 事件</span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">在 exit 事件中,只能执行同步操作。在调用 'exit' 事件监听器之后,Node.js 进程将立即退出,从而导致在事件循环中仍排队的任何其他工作被放弃。</p> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; margin: 10px auto; height: 40px; background-color: rgb(251, 251, 251); border-bottom: 1px solid rgb(246, 246, 246); overflow: hidden; box-sizing: border-box;"><span style="margin-left: -10px; display: inline-block; width: auto; height: 40px; background-color: rgb(33, 33, 34); border-bottom-right-radius: 100px; color: rgb(255, 255, 255); padding-right: 30px; padding-left: 30px; line-height: 40px; font-size: 16px;">process 的标准流对象</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">process 提供了 3 个标准流。需要注意的是,它们有些在某些时候是同步阻塞的(请见文档)。</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; list-style-type: disc;"> <li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">process.stderr:WriteStream 类型,<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">console.error</code>的底层实现,默认对应屏幕</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">process.stdout:WriteStream 类型,<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">console.log</code>的底层实现,默认对应屏幕</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">process.stdin:ReadStream 类型,默认对应键盘输入</section></li></ul> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">下面是基于“生产者-消费者模型”的读取控制台输入并且及时输出的代码:</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #333; background: #f8f8f8; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">process.stdin.setEncoding(<span class="hljs-string" style="color: #d14; line-height: 26px;">"utf8"</span>);

process.stdin.on(<span class="hljs-string" style="color: #d14; line-height: 26px;">"readable"</span>, () => { <span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">let</span> chunk; <span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">while</span> ((chunk = process.stdin.read()) !== <span class="hljs-literal" style="color: #008080; line-height: 26px;">null</span>) { process.stdout.write(<span class="hljs-string" style="color: #d14; line-height: 26px;">&gt;&gt;&gt; <span class="hljs-subst" style="color: #333; font-weight: normal; line-height: 26px;">${chunk}</span></span>); } });

process.stdin.on(<span class="hljs-string" style="color: #d14; line-height: 26px;">"end"</span>, () => { process.stdout.write(<span class="hljs-string" style="color: #d14; line-height: 26px;">"结束"</span>); }); </code></pre>

<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">关于事件的含义,还是请看<a href="http://nodejs.cn/api/stream.html" style="text-decoration: none; word-wrap: break-word; font-weight: bold; color: rgb(239, 112, 96); border-bottom: 1px solid rgb(239, 112, 96);">stream 的文档</a>。</p> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; margin: 10px auto; height: 40px; background-color: rgb(251, 251, 251); border-bottom: 1px solid rgb(246, 246, 246); overflow: hidden; box-sizing: border-box;"><span style="margin-left: -10px; display: inline-block; width: auto; height: 40px; background-color: rgb(33, 33, 34); border-bottom-right-radius: 100px; color: rgb(255, 255, 255); padding-right: 30px; padding-left: 30px; line-height: 40px; font-size: 16px;">深入理解 process.nextTick</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">我第一次看到 process.nextTick 的时候是比较懵的,看文档可以知道,它的用途是:把回调函数作为微任务,放入事件循环的任务队列中。但这么做的意义是什么呢?</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">因为 nodejs 并不适合计算密集型的应用,一个进程就一个线程,在当下时间点上,就一个事件在执行。那么,如果我们的事件占用了很多 cpu 时间,那么之后的事件就要等待非常久。所以,<strong style="font-weight: bold; color: black;">nodejs 的一个编程原则是尽量缩短每一个事件的执行事件</strong>。process.nextTick 的作用就在这,<strong style="font-weight: bold; color: black;">将一个大的任务分解成多个小的任务</strong>。示例代码如下:</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #333; background: #f8f8f8; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-comment" style="color: #998; font-style: italic; line-height: 26px;">// 被拆分成2个函数执行</span> <span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">function</span> <span class="hljs-title" style="color: #900; font-weight: bold; line-height: 26px;">BigThing</span>(<span class="hljs-params" style="line-height: 26px;"></span>) </span>{ doPartThing();

process.nextTick(<span class="hljs-function" style="line-height: 26px;"><span class="hljs-params" style="line-height: 26px;">()</span> =&gt;</span> finishThing());

} </code></pre>

<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">在事件循环中,何时执行 nextTick 注册的任务呢?请看下面的代码:</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #333; background: #f8f8f8; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">setTimeout(<span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">function</span>(<span class="hljs-params" style="line-height: 26px;"></span>) </span>{ <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(<span class="hljs-string" style="color: #d14; line-height: 26px;">"第一个1秒"</span>); process.nextTick(<span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">function</span>(<span class="hljs-params" style="line-height: 26px;"></span>) </span>{ <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(<span class="hljs-string" style="color: #d14; line-height: 26px;">"第一个1秒:nextTick"</span>); }); }, <span class="hljs-number" style="color: #008080; line-height: 26px;">1000</span>);

setTimeout(<span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">function</span>(<span class="hljs-params" style="line-height: 26px;"></span>) </span>{ <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(<span class="hljs-string" style="color: #d14; line-height: 26px;">"第2个1秒"</span>); }, <span class="hljs-number" style="color: #008080; line-height: 26px;">1000</span>);

<span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(<span class="hljs-string" style="color: #d14; line-height: 26px;">"我要输出1"</span>);

process.nextTick(<span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">function</span>(<span class="hljs-params" style="line-height: 26px;"></span>) </span>{ <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(<span class="hljs-string" style="color: #d14; line-height: 26px;">"nextTick"</span>); });

<span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(<span class="hljs-string" style="color: #d14; line-height: 26px;">"我要输出2"</span>); </code></pre>

<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">输出的结果如下,nextTick 是早于 setTimeout:</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #333; background: #f8f8f8; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">我要输出<span class="hljs-number" style="color: #008080; line-height: 26px;">1</span> 我要输出<span class="hljs-number" style="color: #008080; line-height: 26px;">2</span> nextTick 第一个<span class="hljs-number" style="color: #008080; line-height: 26px;">1</span>秒 第一个<span class="hljs-number" style="color: #008080; line-height: 26px;">1</span>秒:nextTick 第<span class="hljs-number" style="color: #008080; line-height: 26px;">2</span>个<span class="hljs-number" style="color: #008080; line-height: 26px;">1</span>秒 </code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">在浏览器端,nextTick 会退化成 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">setTimeout(callback, 0)</code>。但在 nodejs 中请使用 nextTick 而不是 setTimeout,前者效率更高,并且严格来说,两者创建的事件在任务队列中顺序并不一样(请看前面的代码)。</p> <h1 data-tool="mdnice编辑器" style="font-weight: bold; color: black; font-size: 28px; margin-top: -0.46em; margin-bottom: 0.1em; border-bottom: 2px solid rgb(198, 196, 196); box-sizing: border-box;"><span style="padding-top: 5px; padding-bottom: 5px; color: rgb(160, 160, 160); font-size: 13px; line-height: 2; box-sizing: border-box;">子进程:child_process模块</span></h1> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">掌握 nodejs 的 child_process 模块能够极大提高 nodejs 的开发能力,例如主从进程来优化 CPU 计算的问题,多进程开发等等。本文从以下几个方面介绍 child_process 模块的使用:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; list-style-type: disc;"> <li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">创建子进程</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">父子进程通信</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">独立子进程</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">进程管道</section></li></ul> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; margin: 10px auto; height: 40px; background-color: rgb(251, 251, 251); border-bottom: 1px solid rgb(246, 246, 246); overflow: hidden; box-sizing: border-box;"><span style="margin-left: -10px; display: inline-block; width: auto; height: 40px; background-color: rgb(33, 33, 34); border-bottom-right-radius: 100px; color: rgb(255, 255, 255); padding-right: 30px; padding-left: 30px; line-height: 40px; font-size: 16px;">创建子进程</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">nodejs 的 child_process 模块创建子进程的方法:spawn, fork, exec, execFile。它们的关系如下:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; list-style-type: disc;"> <li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">fork, exec, execFile 都是通过 spawn 来实现的。</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">exec 默认会创建 shell。execFile 默认不会创建 shell,意味着不能使用 I/O 重定向、file glob,但效率更高。</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">spawn、exec、execFile 都有同步版本,可能会造成进程阻塞。</section></li></ul> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;"><code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">child_process.spawn()</code>的使用:</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #333; background: #f8f8f8; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">const</span> { spawn } = <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">require</span>(<span class="hljs-string" style="color: #d14; line-height: 26px;">"child_process"</span>); <span class="hljs-comment" style="color: #998; font-style: italic; line-height: 26px;">// 返回ChildProcess对象,默认情况下其上的stdio不为null</span> <span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">const</span> ls = spawn(<span class="hljs-string" style="color: #d14; line-height: 26px;">"ls"</span>, [<span class="hljs-string" style="color: #d14; line-height: 26px;">"-lh"</span>]);

ls.stdout.on(<span class="hljs-string" style="color: #d14; line-height: 26px;">"data"</span>, data => { <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(<span class="hljs-string" style="color: #d14; line-height: 26px;">stdout: <span class="hljs-subst" style="color: #333; font-weight: normal; line-height: 26px;">${data}</span></span>); });

ls.stderr.on(<span class="hljs-string" style="color: #d14; line-height: 26px;">"data"</span>, data => { <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.error(<span class="hljs-string" style="color: #d14; line-height: 26px;">stderr: <span class="hljs-subst" style="color: #333; font-weight: normal; line-height: 26px;">${data}</span></span>); });

ls.on(<span class="hljs-string" style="color: #d14; line-height: 26px;">"close"</span>, code => { <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(<span class="hljs-string" style="color: #d14; line-height: 26px;">子进程退出,退出码 <span class="hljs-subst" style="color: #333; font-weight: normal; line-height: 26px;">${code}</span></span>); }); </code></pre>

<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;"><code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">child_process.exec()</code>的使用:</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #333; background: #f8f8f8; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">const</span> { exec } = <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">require</span>(<span class="hljs-string" style="color: #d14; line-height: 26px;">"child_process"</span>); <span class="hljs-comment" style="color: #998; font-style: italic; line-height: 26px;">// 通过回调函数来操作stdio</span> exec(<span class="hljs-string" style="color: #d14; line-height: 26px;">"ls -lh"</span>, (err, stdout, stderr) =&gt; { <span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">if</span> (err) { <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.error(<span class="hljs-string" style="color: #d14; line-height: 26px;">`执行的错误: <span class="hljs-subst" style="color: #333; font-weight: normal; line-height: 26px;">${err}</span>`</span>); <span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">return</span>; } <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(<span class="hljs-string" style="color: #d14; line-height: 26px;">`stdout: <span class="hljs-subst" style="color: #333; font-weight: normal; line-height: 26px;">${stdout}</span>`</span>); <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.error(<span class="hljs-string" style="color: #d14; line-height: 26px;">`stderr: <span class="hljs-subst" style="color: #333; font-weight: normal; line-height: 26px;">${stderr}</span>`</span>); }); </code></pre> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; margin: 10px auto; height: 40px; background-color: rgb(251, 251, 251); border-bottom: 1px solid rgb(246, 246, 246); overflow: hidden; box-sizing: border-box;"><span style="margin-left: -10px; display: inline-block; width: auto; height: 40px; background-color: rgb(33, 33, 34); border-bottom-right-radius: 100px; color: rgb(255, 255, 255); padding-right: 30px; padding-left: 30px; line-height: 40px; font-size: 16px;">父子进程通信</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;"><code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">fork()</code>返回的 ChildProcess 对象,监听其上的 message 事件,来接受子进程消息;调用 send 方法,来实现 IPC。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">parent.js 代码如下:</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #333; background: #f8f8f8; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">const</span> { fork } = <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">require</span>(<span class="hljs-string" style="color: #d14; line-height: 26px;">"child_process"</span>); <span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">const</span> cp = fork(<span class="hljs-string" style="color: #d14; line-height: 26px;">"./sub.js"</span>); cp.on(<span class="hljs-string" style="color: #d14; line-height: 26px;">"message"</span>, msg =&gt; { <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(<span class="hljs-string" style="color: #d14; line-height: 26px;">"父进程收到消息:"</span>, msg); }); cp.send(<span class="hljs-string" style="color: #d14; line-height: 26px;">"我是父进程"</span>); </code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">sub.js 代码如下:</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #333; background: #f8f8f8; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">process.on(<span class="hljs-string" style="color: #d14; line-height: 26px;">"message"</span>, m =&gt; { <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(<span class="hljs-string" style="color: #d14; line-height: 26px;">"子进程收到消息:"</span>, m); });

process.send(<span class="hljs-string" style="color: #d14; line-height: 26px;">"我是子进程"</span>); </code></pre>

<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">运行后结果:</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #333; background: #f8f8f8; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">父进程收到消息: 我是子进程 子进程收到消息: 我是父进程 </code></pre> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; margin: 10px auto; height: 40px; background-color: rgb(251, 251, 251); border-bottom: 1px solid rgb(246, 246, 246); overflow: hidden; box-sizing: border-box;"><span style="margin-left: -10px; display: inline-block; width: auto; height: 40px; background-color: rgb(33, 33, 34); border-bottom-right-radius: 100px; color: rgb(255, 255, 255); padding-right: 30px; padding-left: 30px; line-height: 40px; font-size: 16px;">独立子进程</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">在正常情况下,父进程一定会等待子进程退出后,才退出。如果想让父进程先退出,不受到子进程的影响,那么应该:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; list-style-type: disc;"> <li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">调用 ChildProcess 对象上的<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">unref()</code></section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;"><code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">options.detached</code> 设置为 true</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">子进程的 stdio 不能是连接到父进程</section></li></ul> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">main.js 代码如下:</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #333; background: #f8f8f8; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">const</span> { spawn } = <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">require</span>(<span class="hljs-string" style="color: #d14; line-height: 26px;">"child_process"</span>); <span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">const</span> subprocess = spawn(process.argv0, [<span class="hljs-string" style="color: #d14; line-height: 26px;">"sub.js"</span>], { <span class="hljs-attr" style="line-height: 26px;">detached</span>: <span class="hljs-literal" style="color: #008080; line-height: 26px;">true</span>, <span class="hljs-attr" style="line-height: 26px;">stdio</span>: <span class="hljs-string" style="color: #d14; line-height: 26px;">"ignore"</span> });

subprocess.unref(); </code></pre>

<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">sub.js 代码如下:</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #333; background: #f8f8f8; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">setInterval(<span class="hljs-function" style="line-height: 26px;"><span class="hljs-params" style="line-height: 26px;">()</span> =&gt;</span> {}, <span class="hljs-number" style="color: #008080; line-height: 26px;">1000</span>); </code></pre> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; margin: 10px auto; height: 40px; background-color: rgb(251, 251, 251); border-bottom: 1px solid rgb(246, 246, 246); overflow: hidden; box-sizing: border-box;"><span style="margin-left: -10px; display: inline-block; width: auto; height: 40px; background-color: rgb(33, 33, 34); border-bottom-right-radius: 100px; color: rgb(255, 255, 255); padding-right: 30px; padding-left: 30px; line-height: 40px; font-size: 16px;">进程管道</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">options.stdio 选项用于配置在父进程和子进程之间建立的管道。 默认情况下,子进程的 stdin、 stdout 和 stderr 会被重定向到 ChildProcess 对象上相应的 subprocess.stdin、subprocess.stdout 和 subprocess.stderr 流。 这意味着可以通过监听其上的 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(239, 112, 96);">data</code>事件,在父进程中获取子进程的 I/O 。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">可以用来实现“重定向”:</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #333; background: #f8f8f8; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">const</span> fs = <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">require</span>(<span class="hljs-string" style="color: #d14; line-height: 26px;">"fs"</span>); <span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">const</span> child_process = <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">require</span>(<span class="hljs-string" style="color: #d14; line-height: 26px;">"child_process"</span>);

<span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">const</span> subprocess = child_process.spawn(<span class="hljs-string" style="color: #d14; line-height: 26px;">"ls"</span>, { <span class="hljs-attr" style="line-height: 26px;">stdio</span>: [ <span class="hljs-number" style="color: #008080; line-height: 26px;">0</span>, <span class="hljs-comment" style="color: #998; font-style: italic; line-height: 26px;">// 使用父进程的 stdin 用于子进程。</span> <span class="hljs-string" style="color: #d14; line-height: 26px;">"pipe"</span>, <span class="hljs-comment" style="color: #998; font-style: italic; line-height: 26px;">// 把子进程的 stdout 通过管道传到父进程 。</span> fs.openSync(<span class="hljs-string" style="color: #d14; line-height: 26px;">"err.out"</span>, <span class="hljs-string" style="color: #d14; line-height: 26px;">"w"</span>) <span class="hljs-comment" style="color: #998; font-style: italic; line-height: 26px;">// 把子进程的 stderr 定向到一个文件。</span> ] }); </code></pre>

<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0; color: black; box-sizing: border-box; margin-bottom: 16px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 15px; text-align: start; white-space: normal; text-size-adjust: auto; line-height: 1.75em;">也可以用来实现"管道运算符":</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #333; background: #f8f8f8; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">const</span> { spawn } = <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">require</span>(<span class="hljs-string" style="color: #d14; line-height: 26px;">"child_process"</span>);

<span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">const</span> ps = spawn(<span class="hljs-string" style="color: #d14; line-height: 26px;">"ps"</span>, [<span class="hljs-string" style="color: #d14; line-height: 26px;">"ax"</span>]); <span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">const</span> grep = spawn(<span class="hljs-string" style="color: #d14; line-height: 26px;">"grep"</span>, [<span class="hljs-string" style="color: #d14; line-height: 26px;">"ssh"</span>]);

ps.stdout.on(<span class="hljs-string" style="color: #d14; line-height: 26px;">"data"</span>, data => { grep.stdin.write(data); });

ps.stderr.on(<span class="hljs-string" style="color: #d14; line-height: 26px;">"data"</span>, err => { <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.error(<span class="hljs-string" style="color: #d14; line-height: 26px;">ps stderr: <span class="hljs-subst" style="color: #333; font-weight: normal; line-height: 26px;">${err}</span></span>); });

ps.on(<span class="hljs-string" style="color: #d14; line-height: 26px;">"close"</span>, code => { <span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">if</span> (code !== <span class="hljs-number" style="color: #008080; line-height: 26px;">0</span>) { <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(<span class="hljs-string" style="color: #d14; line-height: 26px;">ps 进程退出,退出码 <span class="hljs-subst" style="color: #333; font-weight: normal; line-height: 26px;">${code}</span></span>); } grep.stdin.end(); });

grep.stdout.on(<span class="hljs-string" style="color: #d14; line-height: 26px;">"data"</span>, data => { <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(data.toString()); });

grep.stderr.on(<span class="hljs-string" style="color: #d14; line-height: 26px;">"data"</span>, data => { <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.error(<span class="hljs-string" style="color: #d14; line-height: 26px;">grep stderr: <span class="hljs-subst" style="color: #333; font-weight: normal; line-height: 26px;">${data}</span></span>); });

grep.on(<span class="hljs-string" style="color: #d14; line-height: 26px;">"close"</span>, code => { <span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">if</span> (code !== <span class="hljs-number" style="color: #008080; line-height: 26px;">0</span>) { <span class="hljs-built_in" style="color: #0086b3; line-height: 26px;">console</span>.log(<span class="hljs-string" style="color: #d14; line-height: 26px;">grep 进程退出,退出码 <span class="hljs-subst" style="color: #333; font-weight: normal; line-height: 26px;">${code}</span></span>); } }); </code></pre>

<h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; margin: 10px auto; height: 40px; background-color: rgb(251, 251, 251); border-bottom: 1px solid rgb(246, 246, 246); overflow: hidden; box-sizing: border-box;"><span style="margin-left: -10px; display: inline-block; width: auto; height: 40px; background-color: rgb(33, 33, 34); border-bottom-right-radius: 100px; color: rgb(255, 255, 255); padding-right: 30px; padding-left: 30px; line-height: 40px; font-size: 16px;">参考链接</span></h2> <ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; list-style-type: disc;"> <li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;"><a href="http://nodejs.cn/api/stream.html" style="text-decoration: none; word-wrap: break-word; font-weight: bold; color: rgb(239, 112, 96); border-bottom: 1px solid rgb(239, 112, 96);">Nodejs v12 Stream 文档</a></section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;"><a href="http://nodejs.cn/api/process.html" style="text-decoration: none; word-wrap: break-word; font-weight: bold; color: rgb(239, 112, 96); border-bottom: 1px solid rgb(239, 112, 96);">Nodejs v12 process 文档</a></section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;"><a href="https://juejin.im/post/5d5158eff265da03e83b60ce" style="text-decoration: none; word-wrap: break-word; font-weight: bold; color: rgb(239, 112, 96); border-bottom: 1px solid rgb(239, 112, 96);">nodejs 学习笔记</a></section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;"><a href="https://juejin.im/post/5c4c0ee8f265da61117aa527" style="text-decoration: none; word-wrap: break-word; font-weight: bold; color: rgb(239, 112, 96); border-bottom: 1px solid rgb(239, 112, 96);">一篇文章构建你的 NodeJS 知识体系</a></section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;"><a href="https://bennyzheng.github.io/archivers/2016/12/node-process/" style="text-decoration: none; word-wrap: break-word; font-weight: bold; color: rgb(239, 112, 96); border-bottom: 1px solid rgb(239, 112, 96);">Node.js - 进程学习笔记</a></section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;"><a href="https://baike.baidu.com/item/glob/9515871?fr=aladdin" style="text-decoration: none; word-wrap: break-word; font-weight: bold; color: rgb(239, 112, 96); border-bottom: 1px solid rgb(239, 112, 96);">glob</a></section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;"><a href="https://www.cnblogs.com/chyingp/p/node-learning-guide-child_process.html" style="text-decoration: none; word-wrap: break-word; font-weight: bold; color: rgb(239, 112, 96); border-bottom: 1px solid rgb(239, 112, 96);">Nodejs 进阶:如何玩转子进程(child_process)</a></section></li></ul> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; margin: 10px auto; height: 40px; background-color: rgb(251, 251, 251); border-bottom: 1px solid rgb(246, 246, 246); overflow: hidden; box-sizing: border-box;"><span style="margin-left: -10px; display: inline-block; width: auto; height: 40px; background-color: rgb(33, 33, 34); border-bottom-right-radius: 100px; color: rgb(255, 255, 255); padding-right: 30px; padding-left: 30px; line-height: 40px; font-size: 16px;">放在最后</span></h2> <ol data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; list-style-type: decimal;"> <li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">觉得不错,<strong style="font-weight: bold; color: black;">帮忙点个赞呗</strong>,您的支持是对我最大的激励</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; color: rgb(1,1,1); font-weight: 500; font-size: 15px; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">欢迎我的公众号:<strong style="font-weight: bold; color: black;">「心谭博客」</strong>,只专注于<strong style="font-weight: bold; color: black;">前端</strong> + <strong style="font-weight: bold; color: black;">算法</strong>的原创分享</section></li></ol> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px;"><img src="https://tva1.sinaimg.cn/large/006tNbRwly1g9xhhp50jpj31bi0hcju4.jpg" alt style="display: block; margin: 0 auto; width: 100%;"></figure> </section>

原文出处:https://www.cnblogs.com/geyouneihan/p/12251390.html

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部