07月08, 2014

关于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的发展增加了一些不确定性。

本文链接:http://welefen.com/post/about-tj-farewell-node.js-article.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。