基于MongoSkin的Promise风格的数据库读写示例

Promise是一种异步编程的代码书写方式,和Async模块一样,都能提高代码的可读性和可维护性。Async封装的比Promise要好,但是灵活性特别是彻底的去CallBack化会比Promise要差一点。下面直接贴下源代码,注释很详细:

(1)数据库连接文件:dbConfig

/**
 * Created by apple on 2014/12/29.
 */
var mongoskin = require(‘mongoskin‘);
var db = null;
var dbName = "yqbChat";

/**
 * @function
 * @param collectionName
 * @returns {SkinCollection|null|*}
 */
exports.getCollection = function (collectionName) {
    if (!db) {
        //连接本机mongodb ,使用帐号密码连接 mongoskin.db(‘username:[email protected]服务器ip/数据库名
        db = mongoskin.db(‘mongodb://127.0.0.1:27017/‘ + dbName + ‘?auto_reconnect=true&poolSize=3‘,
            {numberOfRetries: 1, retryMiliSeconds: 500, safe: true, native_parser: true},
            {socketOptions: {timeout: 5000}}
        );
    }
    return db.collection(collectionName);
};

/**
 * @function 关闭数据库
 */
exports.dbClose = function()
{
    if (!db) {
        db.close();
    }
};

(2)Model 层文件

/**
 * Created by apple on 2015/1/17.
 */
/** 聊天室数据结构
 *
 * //某两个用户对应的聊天室为一个集合,一个消息为一个文档
 * @{singleChatRoomID}
 *  @_id 信息编号
 *  @msgState 0-未读 1-已读 (int类型)
 *  @msgContent 消息内容
 *  @msgSend 消息发送者的user_id
 *  @create_time
 *
 */

//获取MongoDB的连接实例
var moment = require(‘moment‘);
var Q = require("q");

//存放聊天室配置集合
var singleChatRoomConfigInstance = null;

//当前时间点
var currentDateTime = moment().format("YYYY-M-D H:m:s");

/**
 * @function 根据singleChatRoomID在singleChatRoomConfig文档中搜索配置信息
 * @param singleChatRoomID 聊天室ID
 * @param callback 回调函数 如果为promise为空
 * @param promise 如果存在promise,则callback为空
 */
exports.findSingleChatRoomByID = function (data) {

    //根据singleChatRoomID搜索对应聊天室的配置,如果存在则返回聊天室配置,否则返回false
    if (singleChatRoomConfigInstance == null) {
        singleChatRoomConfigInstance = data.db.getCollection(‘singleChatRoomConfig‘);
    }

    var deferred = Q.defer();
    console.log("[SingleChatRoomConfig->findSingleChatRoomByID]:开始根据聊天室ID查找配置数据!");
    //查询
    singleChatRoomConfigInstance.findOne({singleChatRoomID: data.singleChatRoomID}, function (error, result) {

        if (typeof data.promise != undefined) {
            if (!error) {
                data.result = result;
                //console.log(data);
                deferred.resolve(data);
            } else {
                deferred.reject(error);
            }
        }
        else {
            callback(error, data);
        }
        //db.dbClose();
    });

    return deferred.promise;

};

/**
 * @function 在聊天室配置集合中插入新的集合
 * @param singleChatRoomID
 * @param user_id_1
 * @param user_id_2
 * @param callback
 * @param promise
 */
exports.insertSingleChatRoomByID = function (data) {
    //根据singleChatRoomID搜索对应聊天室的配置,如果存在则返回聊天室配置,否则返回false
    if (singleChatRoomConfigInstance == null) {
        singleChatRoomConfigInstance = data.db.getCollection(‘singleChatRoomConfig‘);
    }

    var deferred = Q.defer();
    console.log("[SingleChatRoomConfig->insertSingleChatRoomByID]:开始插入数据!");
    //console.log(data);
    singleChatRoomConfigInstance.insert(
        {
            singleChatRoomID: data.singleChatRoomID,
            users: [data.user_id_1, data.user_id_2],
            msgCount: 0,
            createTime: currentDateTime
        }, function (error, result) {
            if (typeof data.promise != undefined) {
                if (!error) {
                    data.result = result;
                    deferred.resolve(data);
                } else {
                    deferred.reject(error);
                }
                //db.dbClose();
            }
            else {
                callback(error, result);
                //db.dbClose();
            }

        }
    );
    return deferred.promise;

};

(3)Test文件

/**
 * Created by apple on 2015/1/17.
 */
var singleRoomConfigModel = require(‘../SingleRoomConfigModel‘);
var model = require(‘../Model‘);
var db = require(‘../db/dbConfig‘);
var Q = require("q");

/**
 * @function 测试在singleChatRoomConfig中查询是否存在某个聊天室的配置记录,不存在则创建
 * @param singleChatRoomID
 */
/**CallBack风格的函数*/
function testFindAndInsertByID_CALLBACK(singleChatRoomID) {
    //执行查询操作的回调函数
    this.findSingleChatRoomByIDCallBack = function (error, result) {

        console.dir("findSingleChatRoomByIDCallBack invoked!" + result);

        //如果结果不为空,则查询所有未读信息
        if (result != null) {

        }
        else
        //如果结果为空,则建立一条新的数据返回未读信息条数为空
        {
            singleRoomConfigModel.insertSingleChatRoomByID(singleChatRoomID, 1, 2, this.insertSingleChatRoomByIDCallBack);
        }

    };
    //执行插入操作的回调函数
    this.insertSingleChatRoomByIDCallBack = function (error, result) {

        if (error != null) {
            console.log(result);
        }
        else {
            console.error(error);
        }

    };
    singleRoomConfigModel.findSingleChatRoomByID(singleChatRoomID, this.findSingleChatRoomByIDCallBack);
}

/**Promise风格的函数*/
function testFindAndInsertByID_PROMISE(singleChatRoomID) {

    var data = {
        singleChatRoomID: singleChatRoomID,
        promise: true,
        db:db
    };

    singleRoomConfigModel.findSingleChatRoomByID(data).then(
        /**
         * @function 逻辑判断层,聊天室存在则返回聊天室信息,否则进入聊天室创建
         * @param result
         */
        function (data) {
            var deferred = Q.defer();
            if(data) {
                //console.log("聊天室存在,输出聊天室配置!");
                deferred.resolve(data);
            }
            else{
                //console.log("聊天室不存在,开始创建聊天室!");
                //继续设置下一层的promise调用
                deferred.reject(data);
            }
            return deferred.promise;
        }
        , model.errorHandler
    ).then(
        function(data){
            //console.log("获取到了聊天室配置!");
            var deferred = Q.defer();
            deferred.resolve(data);
            return deferred.promise;
        },
        singleRoomConfigModel.insertSingleChatRoomByID
    ).done(
        function(data){
            //console.log("testFindAndInsertByID_PROMISE-完毕");
            //console.log(data);
            data.db.dbClose()
        },
        model.errorHandler
    );

}

testFindAndInsertByID_PROMISE("1");
时间: 2024-08-08 22:08:17

基于MongoSkin的Promise风格的数据库读写示例的相关文章

基于nginx的TCP Proxy实现数据库读写分离

nginx非常早就支持tcp proxy.可是一直不知道其使用,近期在nginx blog上看见了.一些实践者将其运用到数据库訪问的负载均衡以及实现读写分离,来提高数据库的吞吐量,这里我不会讲详细的搭建实现.仅仅是最一些理论上的设计猜想. 直接上图 db集群.分为读db和写db.写db向读db同步数据. 读db仅仅能读,写db仅仅能写.图中读写各一个,仅仅是一个样例,实际须要依据业务来配置读写server比例. nginx tcp proxy实现读写分离.提供仅仅读的port和仅仅写的port.

基于Mysql-Proxy实现Mysql的主从复制以及读写分离(上)

基于Mysql-Proxy实现Mysql的主从复制以及读写分离(上) 上周BOSS给分配任务让实现一下Mysql数据库的主从复制以及读写分离,然后花了一盏茶的功夫进行了调研,发现主从复制数据库进行一番配置直接可以实现,而读写分离则需要一些软件的支持,基本上读写分离的实现有两种: Amoeba(变形虫):是由前阿里员工实现的一个以MySQL为底层数据存储,并对应用提供MySQL协议接口的proxy.但是由于没人维护了,而且据说作者也不再回答开发者的问题,所以不予考虑. Mysql-Proxy:是一

MariaDB数据库读写分离实现(二):amoeba的使用

本文接上一篇博客:MariaDB数据库读写分离实现(一):mysql-proxy的使用 http://sohudrgon.blog.51cto.com/3088108/1608605 我们将mysql-proxy停止,在节点node5上安装amoeba,测试实现数据库的读写分离. 一.amoeba的简介     Amoeba for MySQL致力于MySQL的分布式数据库前端代理层,它主要在应用层访问MySQL的时候充当query 路由功能,专注分布式数据库 proxy 开发.座落于Clien

基于Mysql-Proxy实现Mysql的主从复制以及读写分离(下)

基于Mysql-Proxy实现Mysql的主从复制以及读写分离(下) 昨天谈到了Mysql实现主从复制,但由于时间原因并未讲有关读写分离的实现,之所以有读写分离,是为了使数据库拥有双机热备功能,至于双机热备,特指基于高可用系统中的两台服务器的热备(或高可用),因两机高可用在国内使用较多,故得名双机热备,双机高可用按工作中的切换方式分为:主-备方式(Active-Standby方式)和双主机方式(Active-Active方式),主-备方式即指的是一台服务器处于某种业务的激活状态(即Active状

?Postgres-XL:基于PostgreSQL的开源可扩展数据库集群

?Postgres-XL:基于PostgreSQL的开源可扩展数据库集群 最近这一年业界去"IOE"越叫越响,很多传统企业也把去"IOE"计划摆上了桌面.我老是想不明白这些非互联网企业(比如:银行)做这种事的动力何在? 高大上的"自主可控"."振兴民族科技"等空洞口号先不去管,真正的动力在哪里? "安全"."成本"."互联网架构".......等等.等等, 唯一看起来

利用amoeba(变形虫)实现mysql数据库读写分离

关于mysql的读写分离架构有很多,百度的话几乎都是用mysql_proxy实现的.由于proxy是基于lua脚本语言实现的,所以网上不少网友表示proxy效率不高,也不稳定,不建议在生产环境使用:amoeba是阿里开发的一款数据库读写分离的项目(读写分离只是它的一个小功能),由于是基于java编写的,所以运行环境需要安装jdk: 前期准备工作:1.两个数据库,一主一从,主从同步:master: 172.22.10.237:3306 :主库负责写入操作:slave: 10.4.66.58:330

新春好跑步,以及数据库“读写分离”的点滴考虑

新春的好日子: 小风吹来: 花一样的味道: 满满的幸福滋味. 迈开步子在宽敞的马路上跑步,步伐轻盈,多么美好的事情. 跑步总是枯燥的,只有奔跑奔跑: 跑步是孤独的,每个人的都有自己的节奏: 跑步的时候总爱瞎想,昨天和一些同学聊到了数据库的"读写分离". 在我有限的认识中,我一直认为数据库"读写分离",是为了提升数据库的瓶颈,因为数据库写总是相对比较少,而读取可能总是比较多,甚至高几个数量级. 比如一个电子商务网站,把某一个产品上架,可能一个月才需要写一次,但是每天都

【转】mysql数据库读写分离数据同步

转载请注明来源:mysql数据库读写分离数据同步 mysql数据库读写分离数据同步 我是用了两个xp(一个主的,一个从的)的系统测试成功的,linux系统我也做测试了,没有成功,不过我想我所遇到的问题是同一个问题,xp下的可以成功,linux下的应该也可以成功,稍候会测试,然后更新结果! PS:刚测试了下linux 可以同步成功,主服务器是xp,从服务器是centos,可以成功. 例: A机器 192.168.0.2 B机器 192.168.0.3 两个机器可以ping通,互相访问 先配置主服务

C++服务器开发之基于对象的编程风格

Thread.h #ifndef _THREAD_H_ #define _THREAD_H_ #include <pthread.h> #include <boost/function.hpp> class Thread { public: typedef boost::function<void ()> ThreadFunc; explicit Thread(const ThreadFunc& func); void Start(); void Join();