Page 160 - Node.js开发指南
P. 160
附录 A JavaScript 的高级特性 153
exports.add_user = function(user_info, callback) { 1
var uid = parseInt(user_info['uid']);
mongodb.open(function(err, db) {
if (err) {callback(err); return;}
db.collection('users', function(err, collection) {
if (err) {callback(err); return;}
collection.ensureIndex("uid", function(err) { 2
if (err) {callback(err); return;}
collection.ensureIndex("username", function(err) {
if (err) {callback(err); return;}
collection.findOne({uid: uid}, function(err) {
3
if (err) {callback(err); return;}
if (doc) {
callback('occupied');
} else {
var user = {
4
uid: uid,
user: user_info,
};
collection.insert(user, function(err) {
callback(err);
}); 5
}
});
});
});
}); 6
});
};
如果你对 Node.js 或 MongoDB 不熟悉,没关系,不需要去理解细节,只要看清楚大概
的逻辑即可。这段代码中用到了闭包的层层嵌套,每一层的嵌套都是一个回调函数。回调函
7
数不会立即执行,而是等待相应请求处理完后由请求的函数回调。我们可以看到,在嵌套的
每一层中都有对 callback 的引用,而且最里层还用到了外层定义的 uid 变量。由于闭包
机制的存在,即使外层函数已经执行完毕,其作用域内申请的变量也不会释放,因为里层的
函数还有可能引用到这些变量,这样就完美地实现了嵌套的异步回调。 8
尽管可以这么做,上面这种回调函数深层嵌套的实现并不优美,本书
第 6 章中介绍了控制流优化的方法。
9
2. 实现私有成员
我们知道,JavaScript 的对象没有私有属性,也就是说对象的每一个属性都是曝露给外部
的。这样可能会有安全隐患,譬如对象的使用者直接修改了某个属性,导致对象内部数据的一
10
致性受到破坏等。JavaScript通过约定在所有私有属性前加上下划线(例如_myPrivateProp),