关于Node.js下的MongoDB阻塞模式实现
注:本文仅为我初学 Node.JS 的时候的稚嫩笔记。是从 http://web.archive.org/ 扒回来的。现在看来已无多大参考价值,各位可以略过。我只是把它扒回来纪念一下而已,以记录我的历程。而那个相对应的 SevenzJS
也已经被遗弃
背景
最近在做公司项目的一个模块,主要用于 JSON Api 的传输,所以开发环境的目标就锁定在了 Node.js。而这一块的登陆用户又是存在 MongoDB 里面的,所以就有了如下的问题。
- 网上的 Node.JS 框架都比较重型或者臃肿的,学了 Node 之后还需要学额外的东西。
- 所以我就打算自己写一个专注于 JSON Api 的快速开发框架,于是有了 SevenJS。
- 问题出现了,虽然 Node.JS 极度推崇异步非阻塞模式,但是阻塞模式在平常开发中还是太常用了。
我们试想一下,如果我们有几句MongoDB的查询之类的,用node-mongodb-native来写的话是这样的:
var client = new Db('test', new Server("127.0.0.1", 27017, {})); |
各种嵌套回调有木有!这不是我们想要的,尤其是我的那个框架,因为我的框架是流式的。
所以我就想有这样的一种方案:
var client = mongodb.connect(); |
使得这样就能找出dbname表下的foo为bar值的记录了。
正题
出于这样的想法,我在网上找遍了大江南北,除了 CNode 社区有人问到了类似的问题以外,再也找不到音信了,而且那里也没有一个好的回答。
不过这也正常,因为 Node.js 官方本身就不推荐这么做——他们认为异步非阻塞是非常优雅的一件事情。
包括我在 Node.js 的 IRC 聊天室里面问了这个问题,也有人是这么回答我的:
You can’t use a car as a boat. If you want a boat, use a boat.
言简意赅,直截了当地说明 Node.js 是不支持这样的,如果你想这样做,就用 python 或者 ruby 去吧。
不过好在后来 IRC 里面有人推荐了我一个模块:fibers。
有了这个模块好啊,直接能用了有木有!
接下来就来讲一下如何使用吧:
function find(collection, selector, callback) { |
这就是一个非常简单的同步查询 MongoDB 的例子了,实际上本质还是一个异步,注意到没有,其实 Fiber()
内部的那个 function
本质上还是一个回调函数,只不过在这个回调函数里面,里面的所有 callback
都可以被同步了。不过我们只需要小动一些手脚就能加上这个外壳了。具体请参见 sRouter.js 约 121 行的外壳以及 sMongoSync.js 的实现,加上 index.js 中的查询 demo。
结尾
所以说当我们做不到某件事的时候,多去IRC看看,多去社区混混,也多去找找模块,要真没有的话就只能自己丰衣足食了(我还没到那水平,笑)。总之这次Fibers帮了我一个大忙。
最后,SevenzJS 欢迎 Fork。