4 minute read

为什么我讨厌 node 和 JS

就是讨厌 o((≡^♀^≡))o

容易入门却无法精通

Node 或者说 Javascript 是非常容易上手的,只要你之前有一点点前端的经验,然后再搜一些教程过来看看,很快,就可以使用 Express 做一个网站出来。看着自己的页面你可能会觉得,我现在需要连一下数据库,于是你去 npm 上搜一下,一堆写的比较完整的 SQL ORM 相关的库等着你。你用着用着发现这些 ORM 的库太复杂,还是那些数据库的驱动包装库用起来简单顺手,没问题,NPM 上这些都有。于是你开始编写一大堆的 model 类,和各种各样的数据验证逻辑,还有各种复杂的查询组合。然后你发现所有的这些数据验证、查询都会有一堆的回调函数告诉你结果或是有没有出错。

不论你自己的项目是不是符合我刚刚的描述,你最后都会在无数的 callback 中迷失自己,我估计你大概听说过 callback 地狱,所以你应该已经吃到了苦头,于是你应该已经开始把自己的代码剁碎,然后用某一个 promise 库来封装这些 callback。做到最后你一看整个代码库,基本已经将整个代码库都 Promise 化了。

其实我想说的是,node 的世界一切都在不停的变化,而且这种变化并不是一种好的变化,而是为了变化而变化。新的工具不断出现,新的类库闪着光芒,而且整个社区也似乎非常鼓励这样的现象。你在用 Grunt 做构建?过时了,所有人都在用 Gulp 呢,等等,貌似最新的潮流是直接手写 NPM 脚本。。。。。

那些仅仅只有10行不到的代码也能成为一个类库放在 NPM 上,而且居然还被下载了成千上万次。说真的,你真的需要一个第三方库来帮你检查一个变量的类型是不是 Array 么?但是这样的库居然被 React 和 Babel 这样重头的工具依赖着。

像这种跑断腿的变化速度,你没法真正掌握什么,你也很难遇到和你在一个框架上的其它开发者,更不用说那些项目之间的脆弱的依赖。

撞大运式错误处理

Lua,Golang,C等,用返回值来表示错误,其它的语言,像 Python、Ruby、PHP,用抛出的异常来表示错误,你会很自然的想 Node 也是这两种的一种。但是 node 不,它要把错误的处理变成你回调函数的一部分(或者是 promises 的一部分),没有了异常,当你的逻辑没有走到出错的分支时一切都很完美,但是当你在多重嵌套的回调中发生了错误,光是想要看清楚调用栈就要好久,更不用说如果你忘了在你的回调中处理某个错误,它会继续跑下去,直到触发了一堆其它的错误。

就算你自己制定了一套完备的错误处理守则,你也没法保证你用的类库里面也照着你的规矩走。

这个问题最终导致了大家都会在 node 里面写一个全局的,处理所有种类错误的函数。不过脱离了具体错误的环境,这个函数能做的事无非就是打印一下错误的描述和堆栈(这个堆栈不一定包括了错误产生的具体函数),然后”优雅”的把自己的程序给退了。因为,要知道,我们的 node 是单线程架构,如果有啥问题锁住了进程,后面所有的东西都会被阻塞,所以将程序退出是最好的选择。不过没关系,我们用 node 的,都会有一个 forerver 的守护进程在边上等着,一会就自己起来了~

回调、promises 还是 generators

为了解决 callback 地狱(说的像是 Windows 的 DLL 地狱解决了一样),大部分程序员都在用 promises,让你用同步的方式写那些异步的回调逻辑。但是可惜的是,依然没有什么标准去规定 Promises 应该怎么实现和怎么去用。

在 Promises 的一堆库中,最好用的感觉是 Bluebird 不过里面还是有很多看起来非常黑科技的代码。之后主流开始使用 async 来管理回调,不过最近听说 Generators 模式开始流行了,但是我还没时间去关心。

没有标准

JS 并不是没有标准,它有一个专门的委员会提出标准,比如现在通用的 ES5 脚本标准,或是正在推行的 ES6 标准。但实现和维护 JS 虚拟机的却是多种多样的机构,各大浏览器都有自己的 JS 虚拟机,每家标准的支持力度都不同,没有一个像是其它语言的独立社区去维护(就算是 python 如此不团结的社区,依然是有个社区啊),造成不论是标准实施的细节,还是一些具体的编程范式都没有统一的标准。

如何处理错误?一家用回调,一家用返回值。如何处理打包?每个社区都有自己的喜好。放狗搜一下所谓的 “Javascript Coding Standards” 你就会对当前的乱象有一个认识。

我理解,其实大多数的语言也没有所谓的最佳实践,但不论如何,都会有一份由语言的维护者编写的指导手册。可是在 Javascript 这里,连维护者都不是唯一的。

无意义的总结

Node 在制作小规模的服务或是进行原型开发时,我还是推荐的。但大项目还是不要碰的好。如果你发现你的 node 项目越写越大,趁早重构是最佳的选择。对于 Javascript 语言,最好还是用在那些 Web 前端的项目中(说的好像你还有其它可以选择一样)。无意挑起语言的圣战,因为 JS 还不值得被大家捍卫吧,嘿嘿。

comments powered by Disqus