Node.js V0.12新特性:给子进程的同步API

尽管发明Node.js的初衷主要是为了编写Web服务器,但开发人员又发现了其他适用(和不适用!)Node的用途。令人觉得惊喜的是,这些用途中有一个是编写shell脚本。并且那确实有意义:Node的跨平台支持已经相当好了,既然前端和后端都用JavaScript写了,如果构建系统也用JavaScript写不是更好吗,对吧?

异步对shell脚本的坏处

在这一用途上值得称道的库是Grunt,它是构建在ShellJS之上的。然而ShellJS有一块硬骨头要啃:Node迫使它用异步I/O。尽管对于Web服务器来说异步I/O很棒,因为它必须随时做出响应,但对于需要逐步执行的shell脚本来说,异步I/O意义不大。

所以,ShellJS的作者们发现了一个“有趣的”解决办法,让它可以运行一个shell命令,然后等着命令完成。大致上是下面这样的代码:

var child_process = require('child_process');
var fs = require('fs');

function execSync(command) {
// 在子shell中运行命令
child_process.exec(command + ' 2>&1 1>output && echo done! > done');

// 阻塞事件循环,知道命令执行完
while (!fs.existsSync('done')) {
// 什么都不做
}

// 读取输出
var output = fs.readFileSync('output');

// 删除临时文件。
fs.unlinkSync('output');
fs.unlinkSync('done');

return output;
}

返回栏目页:http://www.bianceng.cnhttp://www.bianceng.cn/webkf/script/

换句话说,在shell执行你的命令时,ShellJS依然在运行,并持续不断地轮询着文件系统,检查是否能找到表明命令已经完成的那个文件。有点儿像驴子。

这种效率低下又丑陋不堪的解决办法让Node核心团队受刺激了,实现了一个真正的解决方案 – Node v0.12最终应该会支持同步运行子进程。实际上这个特性已经在路线图上放了很长时间了– 我记得是在2011年的JSConf.eu上(!) ,跟现在已经退休的Node维护者Felix Geisendoerfer坐在一起,勾勒出了一个实现execSync的办法。在过了两年多以后,这一特性现在终于出现在了master分支上。

恭喜,ShellJS的人们挑了一个很好的刺儿! :)

同步对shell脚本的好处

我们刚加上的API spawnSync跟它的异步小伙伴类似,它提供的底层API让你可以完全掌控子进程的设置。它还会返回所有我们能够收集的信息:退出码、终止信号、可能的启动错误,以及这个进程的全部输出。当然,在流中使用spawnSync没有任何意义-它是同步的,所以事件处理器不能在进程退出前运行-所以进程的所有输出会被缓冲到一个单例字符串或缓冲对象中。

并且就像众所周知的exec(运行shell命令)和execFile(用于运行一个可执行文件)方法一样,我们为常见的情况添加了execSync和execFileSync,它们比spawnSync更易用。如果你用了这些API,Node会假定你关心的只是进程写到stdout中的数据。如果进程或shell返回了非零的退出码,node会认为出现错误了,exec(Sync)会抛出。

比如获取项目git历史的代码就像下面这样简单:

var history = child_process.execSync('git log', { encoding: 'utf8' });
process.stdout.write(history);

现在你可能在想“怎么要用这么长时间?”从表面上看,启动一个子进程并读取它的输出看起来简直是小菜一碟。也确实是这样-如果你只关心非常常见的情况。但是,我们不想做出来的解决方案只是一半。

当需要同时发送输入并读取一或多个输出流时,有两个选择:用线程-或者用事件循环。比如Python的实现,我们发现他们或者用事件循环(在Unix系的平台上)或者用线程(在Windows上)。并且它的实现可真不是一碟小菜。

2011年我们就意识到Node已经有一个非常棒的事件循环库了,即libuv。理论上已经具备了实现这一特性的所有条件。然而总是有或大或小的问题,让它并不能真正可靠地工作。

比如说,当子进程退出时,kernel会给node发送一个SIGCHLD信号通知它,但当有多个事件循环存在时,有很长一段时间libuv都不能正确处理信号。还有,删除事件循环并且不留下堆栈跟踪的能力也是最近才加上的。之前Node根本不管,它只是在某点退出,然后让OS打扫战场。如果我们需要一个临时的事件循环,并且在不需要它后仍然继续运行,这种策略就不太合适了。

慢慢的,随着时间的推移,所有这些问题都被解决了。所以如果你现在再设法看看过去那些缓冲区管理、参数解析、超时处理等诸如此类的东西,你会发现这个特性的核心只是一个事件循环,带子进程、计时器,还有一堆附着在它上面的管道。

如果你不关心它都是如何运作的,只需要看看文档,让node为控制子进程提供的丰富选项震你一下吧。现在谁愿意去把ShellJS修好?:)

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索循环
, 进程
, 运行
, 事件
, node
, libuv
, 一个
, node事件循环
, fs.readFileSync方法
, fs.unlinkSync方法
, fs.existsSync方法
, JS常见通知信息
execfile
node、node.js 安装、node.js 教程、node.js下载、node.js 视频教程,以便于您获取更多的相关知识。

时间: 2024-08-02 22:37:15

Node.js V0.12新特性:给子进程的同步API的相关文章

Node.js V0.12新特性:性能优化

v0.12悠长的开发周期(已经过去九个月了,并且还在继续,是有史以来最长的一次)让核心团队和贡献者们有充分的机会对性能做一些优化.本文会介绍其中最值得注意的几个. 支持塞住模式的可写流 现在可写流可以支持"塞住(corked)"模式,类似于你执行man tcp时见到的socket选项TCP_CORK和TCP_NOPUSH. 当被塞住时,写到流中的数据会排队直到流被重新开塞(uncorked).这样Node.js可以将比较小的写操作合并成比较大的,从而减少系统调用和TCP往返. http

Node.js V0.12新特性:Cluster轮转法负载均衡

回顾Node内置的cluster模块 Node.js固有的单线程模型经常被认为是它的一个软肋.不管你的机器上有多少CPU内核,Node.js能用上的也仅仅是其中之一(某些操作会被有条件地卸载到线程池中.大多数程序只是在CPU的总时间上分了一杯羹,所以更好地利用可用的处理能力并不能起到多大作用). 所以Node.js从v0.8开始,新增加了一个内置的'cluster'模块.你可以用cluster模块设置一个主进程作为管理者,由一或多个工人进程完成实际工作. 让创建"发完就忘"的多进程服务

Node.js V0.12新特性之在单进程中跑多个实例

实例 经常有人提出,希望Node.js能被嵌入到其他程序中,特别是让它能跟其他事件循环整合而且(与此同时)支持多个Node执行情境:也就是说让多个Node实例在同一个进程中和平共处的能力.想象一下,比如有个node-webkit 程序,每个窗口都运行在自己的Node实例上,各窗口彼此相互独立.或者把Node嵌在手机或网络交换机里,处理多连接的路由逻辑,但却只是在单个进程中,并且不久的将来就能实现. 一个客户找到我们,说他们的程序需要这类功能.他们经过调研,肯定了我们在Node核心和libuv上的

Vue.js 2.5新特性介绍

TypeScript TypeScript是一种由微软开发的自由和开源的编程语言.它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程.2012年十月份,微软发布了首个公开版本的TypeScript,在2013年6月19日,微软发布了TypeScript 0.9的正式版本,到目前为止,TypeScript已发展到2.x版本,相关资料可以查看W3C TypeScript入门 安装TypeScript 安装TypeScript主要有两种方式: 通过npm

Xfce 4.12 新特性概览

Xfce 4.12 新特性概览 Xfce 4.12 经过漫长的等待终于发布了,这里向您介绍一下 Xfce 4.12的主要新特性,这里只介绍了外在的一些改进,完整的改进列表请参见  changelogs . 窗口管理器 (xfwm4) 窗口切换器对话框 窗口管理器的 Alt + Tab 对话框现已全面更换主题,还增加了两个新的模式: 列表模式和窗口预览模式.此外用户可以使用鼠标点击选择想要切换的窗口. 传统的对话框现已更换全新主题 列表模式会显示全部窗口的标题 缩略图模式 窗口预览模式会以窗口内容

返璞归真 asp.net mvc (11) - asp.net mvc 4.0 新特性之自宿主 Web API, 在 WebForm 中提供 Web API, 通过 Web API 上传文件, .net 4.5 带来的更方便的异步操作

原文:返璞归真 asp.net mvc (11) - asp.net mvc 4.0 新特性之自宿主 Web API, 在 WebForm 中提供 Web API, 通过 Web API 上传文件, .net 4.5 带来的更方便的异步操作 [索引页][源码下载] 返璞归真 asp.net mvc (11) - asp.net mvc 4.0 新特性之自宿主 Web API, 在 WebForm 中提供 Web API, 通过 Web API 上传文件, .net 4.5 带来的更方便的异步操作

IntelliJ IDEA 12新特性:为Android开发者提供新的XML重构工具

原文 http://www.cnblogs.com/nuliniaoboke/archive/2012/12/07/2807378.html 一直用IntelliJ IDEA做Android开发,感觉挺顺手.刚刚最新的IntelliJ IDEA 12(What's New?)发布,包含众多的新特性,我拣了个Android开发框架相关的特性给大家介绍下.译文如下: 最近,我们为Android XML布局文件添加了新的重构工具.所有的重构现在可以在编辑器中.UI设计器中或者直接在快捷视图中使用. 以

催化剂9.12新特性在Windows 7中的性能对比

在催化剂9.12驱动包中,我们终于看到了一次游戏性能提升,虽说不多但也聊胜于无.接下来就具体看看它和上个版本http://www.aliyun.com/zixun/aggregation/32995.html">在Windows 7里的性能对比. 催化剂9.12在新特性方面带来了对DirectCompute 10.1和OpenGL 3.2的支持,游戏性能提升则有:- 3DMark Vantage:在Radeon HD 5700/5800系列上整体性能提升最多9%,其中GT1 - Jane

深入了解Node.js中的一些特性_node.js

Node.js作为一门新兴的后台语言,旨在帮助程序员快速构建可伸缩的应用程序.Node.js有很多吸引人的地方,有关它的报道不计其数,本文将针对EventEmitter.Streams.Coding Style.Linting.Coding Style等特性进行分析探讨,帮助用户对Node.js有更深入的了解. 作为一个基于Chrome JavaScript 运行时建立的平台,我们对JavaScript 的相关认识,似乎都可应用于node应用程序之上:无需额外的语言扩展或修饰,我们便可以把前端编