如果重写一个类 Nodeclub 的项目,基础框架如何选择:
Koa vs. Express
选用 Koa 可以利用 Node harmony 的 generators 特性来写出没有 callback 的代码,但是增加了学习成本,倒不是 generator 的写法,而是新的思维方式,担心会写出不能发挥 harmony 全部潜能的夹生代码
如果使用 Express ,配合 Bluebird ,也可以写出不那么恐怖的流程控制,假如前段使用 Angular.js ,也是使用类似的 Promise 实现,这样写来前后端不存在思维转换的问题
Mongoose vs. Sequelize
这个倒是没多少纠结,就是非关系型数据库(MongoDB)跟关系型数据库(Mysql、MariaDB、PostgreSQL)的选择
本人并没有多少数据库使用经验,而且一向的观点就是够用就行,如果文件数据库(Sqlite、LevelDB)能满足需求就不上需要额外运行服务的数据库。不过个人倾向于后者,如果选用现在大行其道的 MongoDB ,又会纠结于如何设计出符合 NoSQL 理念的数据库
其实我很想让 Koa 的先行者 @suqian @dead-horse 简单回答下这个问题 http://stackoverflow.com/questions/23099855/koa-co-bluebird-or-q-generators-promises-thunks-interplay-node-js ,以及这个讨论 http://stackoverflow.com/questions/23105693/bluebird-instead-of-co-in-koa 也就是 bluebird 之类的流程控制模块在 Node harmony 的处于何种地位,是不是我们可以完全忘掉他们而全面拥抱 co ?
bluebird挺好的,通过promisifyAll和第三方模块也非常容易集成。 另外bluebird准确地说只是Promise Library而不是流程控制模块
@damngoto 嗯,现在绝大部分第三方模块都没用使用 generators,就算 Node 官方的 api 也需要使用 co 或者 bluebird 包装,所以是否要等到 Node harmony 自生完备之后再使用这些新特性呢
co VS others
流程控制的库我也用过不少,不过从半年多前开始用 co 和 koa 之后,我就几乎没有用过其他的了。之前写过的一个小例子。
- 当代码没有太多业务逻辑的时候,参照 callback hell 指南,不需要其他库就能解决问题。
- 当代码有复杂的业务逻辑的时候,generator 的解决方案以我现在的认知看来是最优的,例如 cnpmjs.org 中
bluebird.conroutine() VS co
bluebird 也有一个类似于 co 的子集: bluebird.coroutine(), 这里 有相关的讨论,里面提到的 bluebird.coroutine() 的优势是堆栈信息更完善,co 的优势是更精简,更易理解。不过以我完全使用 co 和 koa 半年多来看,co 的堆栈信息也已经足够了。
Promise VS thunks
promise 和 thunk 都是 co 中可以 yield 的类型,理论上来说喜欢用哪个就用哪个。不过随着 0.11.13 开始 node 就原生支持了 Promise (不过还有 bug),而 promise 可以用于 co 的同时,也能够被不用 generator 的人使用,因此推荐用 Promise 作为 co 的底层,而不是 thunk,例如:urllib
koa之后,再无express。特别是koa实现了真正意义上的middleware,如果大家写过connect或者express的中间件,有一些需求不通过hack方式是无法实现的。
未来趋势是越来越多库支持promise,那么它默认就是对koa友好的,无需再写一个co wrapper了
我昨天已经用 Express搭了一个框架,看了大家的评论,决定就用 Koa 吧,其实我之前主要担心的是前后端的思维不一致,现在浏览器端也就 Firefox 支持 generator,使用 Node.js 的一个很大的原因就是前后端的一致性,不知道到什么时候才会实现主流平台的全面支持
至于数据库,Sequelize 基于 Promise 的 2.0 版本还处于 unstable 阶段,api 处于随时可变的阶段,所以还是继续使用 Mongoose 吧
请问一下koa中是怎么样将数据库操作、逻辑处理和页面显示分开的那?目前了解到的是这样实现的,都是混在一起的,router.get(’/’, function *(next) { var rows = yield dbHandle.db.query(‘select * from account where studio=?’,[‘全部’]); yield this.render(‘get’, { title: rows[0].userName }); });
koa@2 还挺好理解的...上 koa@2 吧~ 我不说其他的了, 并向你扔了一个 router https://github.com/magicdawn/impress-router
make<br/><br/><a class="form" href="https://github.com/shinygang/Vue-cnodejs">I‘m webapp-cnodejs-vue</a>
make<br/><br/><a class="form" href="https://github.com/shinygang/Vue-cnodejs">I‘m webapp-cnodejs-vue</a>
make<br/><br/><a class="form" href="https://github.com/shinygang/Vue-cnodejs">I‘m webapp-cnodejs-vue</a>
make<br/><br/><a class="form" href="https://github.com/shinygang/Vue-cnodejs">I‘m webapp-cnodejs-vue</a>
make<br/><br/><a class="form" href="https://github.com/shinygang/Vue-cnodejs">I‘m webapp-cnodejs-vue</a>
make<br/><br/><a class="form" href="https://github.com/shinygang/Vue-cnodejs">I‘m webapp-cnodejs-vue</a>