您的位置:首页 > 数据库

使用模块Q的promise机制实现数据库操作的同步问题

2016-06-29 20:41 507 查看
附上上一篇文章链接:

node.js对mongodb的连接&增删改查(附async同步流程控制)(上)

上一篇文章说到,关于耦合度很高的对数据库的连续操作,如何实现同步流程控制呢?使用了async模块的waterfall不顶用。只能使用q模块的proimise方式啦。果然好用。

1.install

npm install q --save


2.require

var Q=require('q');


3.重写数据库CRUD操作方法

/**
* 创建数据库服务器并开发名为databaseName的数据库
* @param host ip
* @param port 端口
* @param databaseName
* @return  打开失败返回-1 ,成功返回database
*/
function openDatabase(host,port,databaseName,collectionName){
//创建数据库所在的服务器

var deferred = Q.defer();
var server = new mongo.Server(host, port, {auto_reconnect: true});
var db = new mongo.Db(databaseName, server, {safe: true});
db.open(function (err, db) {
if (err) {
console.log('打开数据库失败');
deferred.reject(err);
}
else {
console.log('打开数据库成功');
deferred.resolve([db,collectionName]);

}

});
return deferred.promise;
}
/**
* 连接数据集合
* @param db 数据库
* @param collectionName 数据集合名称
* @return 成功返回collection,失败返回-1
*/
function openCollection(db,collectionName){
var deferred = Q.defer();
db.collection(collectionName,{safe:true},function(errcollection,collection){
if(!errcollection){
console.log('连接数据集合成功');
deferred.resolve(collection);

}else{

console.log('连接数集合失败');
deferred.reject(errcollection);
}
});
return deferred.promise;

}
/**
* 插入数据
* @param collection
* @param tmp 要插入的数据
* @return 成功返回collection,失败返回-1
*/
function insertCollection(collection,tmp){
//var tmp = {username:'hello',password:1};
collection.insert(tmp,{safe:true},function(err, result){
if(err){
console.log('传入数据集合失败'+tmp);
return -1;
}else {
console.log('插入数据集合成功'+result);

}
});
return collection;
}
/**
* 查询数据集合 没有条件
* @param collection
* @return 成功返回查询到的数据集合内容,失败返回-1
*/
function findCollectionNoCondition(collection){
var deferred = Q.defer();
collection.find().toArray(function(errfind,cols){
if(!errfind){
console.log('查询数据集合成功'+JSON.stringify(cols));
deferred.resolve(JSON.stringify(cols));
}else {
console.log('查询数据集合失败');
deferred.reject(errfind);
}
});

return deferred.promise;
}
/**
* 查询数据集合 有条件
* @param collection
* @return 成功返回查询到的数据集合内容,失败返回-1
*/
function findCollectionHasCondition(collection,tmp){
collection.find(tmp).toArray(function(errfind,cols){
if(!errfind){
console.log('查询数据集合成功'+JSON.stringify(cols));
return JSON.stringify(cols);
}else {
console.log('查询数据集合失败');
return -1;
}
});
}
/**
* 删除数据集合
* @param collection
* @param tmp
* @return 成功返回数据集合,失败返回-1
*/
function removeCollection(collection,tmp){
//var tmp = {username:'hello',password:1};
collection.remove(tmp,{safe:true},function(err, count){
if(err){
console.log('删除数据集合失败'+tmp);
return -1;
}else {
console.log('删除数据集合成功'+count);
return collection;
}
});
}


里面的关键点是:

定义defered对象
var deferred = Q.defer();


定义函数成功执行的resolve对象
deferred.resolve(JSON.stringify(cols));


定义函数成功失败的error对象
deferred.reject(errfind);


最后返回一个新的promise对象,用来
return deferred.promise;


4.链式调用

user.openDatabase("localhost",27017,"test","users")
.then(function(data){
return user.openCollection(data[0],data[1])
})
.then(user.findCollectionNoCondition)
.done(function(data){
console.log('promise执行成功');
},function(err){
console.log("promise执行失败:"+err);
});


多层嵌套的逻辑瞬间变成了顺序执行。

5.log打印结果

GET / 304 55.922 ms - -
打开数据库成功
连接数据集合成功
GET /stylesheets/style.css 304 6.048 ms - -
查询数据集合成功[{"_id":"57731d3a239f75379769ce31","username":"liuchen","password":"12345"},{"_id":"577328ab5c8d6cf43b3e214d","username":"hello","password":1},{"_id":"577331f35c8d6cf43b3e214e","username":"hello","password":1},{"_id":"57733bf400a7090c35122844","username":"hello","password":1},{"_id":"57733c0300a7090c35122845","username":"hello","password":1},{"_id":"57733c0af8d7813443d51c27","username":"hello","password":1}]
promise执行成功


成功
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据库 mongodb node.js