首先这是一篇翻译自TJ 的 Farewell Node.js ,我本人在看完这这篇文章之后确实是受到了一些冲击,但我并不认同作者的某些看法,比如我认为 Node.js 的package register 是其许多优势之一,反而 Go 在这方面却略显匮乏。 由于个人水平所限,在翻译的时候有许多不懂的地方,我也去作者博客、stackoverflow 上问了一些问题,获得了解答。翻译仍有许多不到位的地方,希望能获得指出意见。
PS. 作为一位Node.js 的入门菜鸟,感谢TJ 的付出,一路走好。
正文:
告别Node.js
离开Node.js领域
我一直与Node.js在生产中一起战斗了足够久的时间,很不幸的是,既然我已经不再喜欢从事这份工作,至少在此刻,这是我的正式告别。更重要的是,我需要维护者。
Node在一些方面确实很棒,但对于最近我感兴趣的软件类型,它终究不是适合的工具。我仍然计划用Node做网站,但如果你对维护任何项目感兴趣,只需要留言写下你的Github 用户名 , npm 用户名,以及项目名称来让我知道。通常我所要求的只有你不彻底的改变已有的api,如果真要这么做的话,还是重新开一个新项目的好。
Koa 是一个我会继续去维护的项目。(与Co 还有朋友们一块)
圣杯的故事
我一直深爱着C,但每一个从事C开发工作的人都知道它是有价值却又易于出错的。很难在日常工作中证明语言的选择,因为它不完全是最快的工作。简洁也是一直赞美它的原因,但是没有大量的模板你不会走得很远。
随着越多的参与分布式系统的开发,Node性能高过可用性与健壮性的发展趋势让我越发沮丧。在过去的一个星期中,我已经用Go重写了一个相对大型的分布式系统,它的健壮性、性能更好,并且易于维护,由于同步代码普遍的更加优美并且更易于开发,它有着更好的可测试覆盖范围。
我并不是说Go就是一个圣杯,它并不完美,但对于现今存在的多种语言来说,Go于我是一个极好的答案。随着越来越多的这些"次世代"语言如 Rust 和 Julia 找到他们自己的位置并成熟起来,我确定我们会有更多的伟大的解决方案。
个人而言我对Go语言感到很兴奋是因为他的迭代速度,很激动的看到他们渴望去达到2.0版本,并且据我所听到的消息,他们并不害怕与打破原有的伟大事物。如果是真的话我很乐意,更多是因为我相信如果真的是有益于这门语言的,就应该快速的打破已有事物。但我也不是一个运行了大量系统的软件巨人。:D
编著: 一定是我错误解读了一些提交的邮件列表,他们在任何时候都并不渴望于做出一些破坏性的改变。@enneff
为什么是Go?
如果Node对你有效并且你没有什么需要担心的,它仍然是一个很好的工具。但如果有些事情困扰着你,别忘了跳出你的盒子去看看在盒子外面有什么其他的--在最初的使用Go来构建产品的几个小时内,我已经被吸引住了。
再次声明,我并不是在那里说Go绝对是最好的语言而且你必须去使用它。但对于它所处年纪来说,是非常成熟而健壮的。(大致与Node相同年纪的时候)。类型的重构是有趣而简单的,Go所提供的作业和调试工具是很棒的,同时社区具有非常强大的关于文档、格式、基准以及api设计方面的条例。
在如此习惯于极度模块化的Node 和体验过 Ruby 腐烂的标准库的同时,当我第一次听到 Go,我认为它的标准库是糟糕的。在我深入这门语言之后,我意识到现阶段极大部分的标准库都是很有必要的,比如compression、json、IO、buffered IO、字符串操作等等。大部分的这些APIS 都被定义的很好并且很强大。很容易仅仅通过使用这些标准库来书写整个程序。
第三方Go packages
大部分的Go 库看上去都很相似,我到目前为止所使用过的大部分的第三方代码都是高质量的,而在Node中很难去找到这些因为JavaScript 吸引了不同技巧层次范围内的开发者。
对于Go 的packages 来说,没有注册中心,所以你通常会同时看到5或6种相同的包。在有些时候,这会造成一定的困惑,但它却有一个有趣的副作用,你必须通过认真的审查每个包来决定哪一个是最佳方案。通过Node 通常有规范的包如 "redis","mongodb-native" 或者"zeromq",所以你会停在那里就推断出他们是最好的一个。
如果你正在做一些分布式的工作,你会发现Go的令人印象深刻的并发基础数据类型是非常有帮助的。我们可以通过在Node 中的generators 来获得相似的东西,但在我看来,generators 仅仅是做到一半而已。没有独立的错误处理、报告栈即使最好也仍然是平凡的。当这些方案都能良好运行的时,我也不想等待社区三年去重整。
在我看来,Go的错误处理是出众的。就你必须考虑每一个错误并且决定怎么做而言,Node是伟大的。然而Node 失败在:
你或许会重复的进行回调
你或许根本不会进行回调 迷失在不稳定状态中 (译注 比如忘记传递错误处理回调,错误时,Node 将吞掉这个错误而不会有任何反馈)
你或许会得到外带的错误
emitters 或许会获得多个错误的事件
忘记错误的事件的处理会毁掉一切
经常不确定什么需要错误的处理
错误的处理是非常冗余的