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),
   155   156   157   158   159   160   161   162   163   164   165