w3ctech

关于TJ大神的Farewell Node.js

TJ大神,express, jade, ejs, co, koa, commandor.js, mocha等众多优秀模块的作者,在Node.js社区里威望非常高。

TJ大神前2天写了一篇Farewell Node.js文章,表示要告别Node.js,转投Go语言。文中TJ详细描述了Node.js的种种缺点,态度委婉,言辞激烈。摘录如下:

The more I’ve been working with distributed systems, the more I’m frustrated by Node’s direction, which favours performance over usability and robustness.

The fact that 4-5 years in we still have vague errors such as “Error: getaddrinfo EADDRINFO” is telling of where the priorities are at. Understandably it’s easy to miss things like that when you’re so focused on building out the core of a system, but I think users have expressed this sort of thing over and over, and we’re not seeing results. We usually get poor responses advocating that what we have is perfect, when in practice it’s anything but.

Streams are broken, callbacks are not great to work with, errors are vague, tooling is not great, community convention is sort of there, but lacking compared to Go. That being said there are certain tasks which I would probably still use Node for, building web sites, maybe the odd API or prototype. If Node can fix some of its fundamental problems then it has good chance at remaining relevant, but the performance over usability argument doesn’t fly when another solution is both more performant and more user-friendly.

If the Node community decides to embrace generators and can implement them to the very core of node, to propagate errors properly then there’s a chance that it would be comparable in that area. This would drastically improve Node’s usability and robustness.

这里看出,TJ不太赞同Node.js的发展方向,注重性能,忽视了可用性和健壮性。同时TJ希望Node.js拥抱es6 generator functions,并作为核心机制来完善错误处理方式,这样可以大大提高Node.js的可用性和健壮性。

TJ对es6 generator functions是非常热爱的,从他写的co模块和koa框架就可以看出。

但目前Node.js v0.10.x系列的稳定版并不支持es6 generator functions,需要在v0.11.x非稳定版本中开启--harmony模式才能使用。对于未来哪个稳定版本中支持es6 generator functions,目前还是个未知数。至于这个是不是TJ放弃Node.js的一个原因,我们不好猜测。

异步的另一种处理方式 - Promise

除了使用es6 generator functions来处理异步,其实还有一种比较好的方式来处理异步,那就是Promise。

Promise虽然也是es6里才纳入标准的,但并不依赖新的JS语法,也就是现有的JS语法也可以实现Promise,比如:es6-promise模块

对于一个供用户访问的WEB服务来说,Node.js中处理一个完整的工作流分为下面几个步骤:

  • 解析url,根据路由规则识别控制器
  • 权限判断
  • 调用控制器对应的逻辑
  • 从数据库、缓存等多个地方获取数据
  • 渲染模版,输出内容到浏览器

这几个步骤中,只要其中一个失败,那么就应该阻止后面的逻辑继续执行。使用Promise的伪代码如下:

//初始化
return initHttp().then(function(){
    return parseUrl(); //解析url
}).then(function(){
    return checkAuth(); //权限判断
}).then(function(){
    return initController(); //初始化控制器
}).then(function(){
    var promise1 = getDataFromAPI();
    var promise2 = getDataFromDb();
    var promise3 = getDataFromCache();
    //从多个不同的渠道拿不同的数据
    return Promise.all([promise1, promise2, promise3]);
}).then(function(){
    return renderTemplate(); //渲染模版
}).then(function(){
    return res.write(content); //输出内容
}).catch(function(){ 
    return res.write(error.message); //流程执行异常,输出错误信息
})

可以看到,使用Promise可以方便清晰的处理http请求的工作流。

  • pendding promise 状态未定的promise,可以阻止后续的逻辑继续执行
  • resolved promise 已解决的promise,可以继续执行后续的then
  • rejected promise 已拒绝的promise, 跳过后续的then,执行后续的catch

如果Node.js基于Promise来构建,可以很好的处理错误。如果Node.js框架基于Promise来构建,就不需要类似express里的各种next了。

当然es6 generator functions也可以和Promise一起使用,配合后效果更加,这里就不具体描述了。

题外话

TJ的离开,对于Node.js社区来说,无疑是个巨大的损失。像他这种精通C等多种语言,对Node.js源代码很熟悉的人来说,当Node.js发展路线跟自己期望一直没法符合的时候,转身离开也许是一种无奈。

而对于WEB前端工程师的我们来说,由于没有TJ那样深厚的技术功底,换一门语言成本较大。遇到Node.js的问题,一般是寻找另一种机制来解决,比如:Promise。

由于依赖google的v8引擎,Node.js未来的发展很大程度上会受限于v8的发展,这无疑给Node.js的发展增加了一些不确定性。

w3ctech微信

扫码关注w3ctech微信公众号

共收到4条回复

  • Generator 去掉 enratr 就是 go 了……

    回复此楼
  • TJ与node开发团队的分歧在去年就有过了,分歧主要在于未来方向。

    在之前的node版本,健壮性(随便一个error没捕获就挂了)、callback魔咒一直困扰着node开发者,也使得很多新人不敢涉足,这些缺点非常明显。

    关于callback的这个,node开发组坚持callback(err,data)这种方法,并不愿意原生支持其它的写法,比如Promise,2012年就因为很多人建议node应当原生提供Promise解决方案,导致开发组的成员特意发博客说:我们认为Promise很有趣很有用,但不会把它加入进nodejs中,如果你觉得不满意,请fork。

    这种理念分歧,持续了好久,直到现在为止,node开发组都坚持callback。

    callback带来的另一大缺点就是异常机制,在callback里的error,没办法在原函数里捕获,所以传统nodejs程序都需要花很多代码加上if(err){}这种东西,这也是低健壮性的一大由来。

    所以有这么一帮程序员(包括TJ)反对callback,但毕竟不是当权的~~

    随便说一下,TJ对nodejs绝对是真爱,他所谓的离开node研究golang,也只是因为对node未来方向的不满,他现在twitter上还一天到晚的说node呢。

    回复此楼
  • @李引证

    > ,TJ对nodejs绝对是真爱

    赞同这个,所以他离开更多的是一种无奈

    回复此楼
  • node 会不会挂啊...我才刚准备学

    回复此楼