最近在用node查询mysql数据库,一个方法里需要做最多5次的纵深查询。
第一个版本写了5层回调,丑陋不堪:
this.insertUser = function(openId, floorName , func ){
var feedback = 'o' ;
var connection = mysql.createConnection(this.DBconfig);
connection.query('INSERT INTO Floor SET ?', {Builder_open_id: openId , Floor_name: floorName }, function(err, result) {
if(err){
//...
}
else{
var floor_id = result.insertId ;
connection.query('INSERT INTO Layer SET ?', { Floor_id: floor_id }, function(err1, result) {
if(err1){
//
}
else{
connection.query('...'. function(err, result){
//some other query below
})
}
})
}
});
};
this.insertFloor = (connection , openId , floorName ) => {
return new Promise( (resolve , reject ) => {
connection.query('INSERT INTO Floor SET ?', {Builder_open_id: openId , Floor_name: floorName }, function(err, result) {
if(err){
reject(err);
}
else{
resolve(result);
}
});
} )
};
然后根据promise的标准写法,以上方法执行完成后需要使用then方法:
this.insertFloor(connection, openId , floorName).then(res=>{
//...
}, err=>{
//...
})
var promise = new Promise(function(resolve, reject) {
if (someCondition) { // succeed
resolve(1);
} else { // fails
reject("err");
}
});
promise.then(function(future) {
console.log(future); // log 1 if someCondition = true
return 2;
}, function(err) {
console.log(err); // log err if someCondition = false
}).then(function(future) {
console.log(future); // log 2 if someCondition = true
});
看到这里你发现return的值是可以传给下一个then的!于是按照文中所说,链式调用then的模型如下:
userdb.query(userid)
.then(function(user) {
return postdb.query(user.latestPost.id);
}).then(function(post) {
return replydb.query(post.latestReply.id);
}).then(function(reply) {
// use reply to do something...
}).catch(function(reason) {
// error handling
});
这个模型比较简单,结合实际的问题,仍然需要考虑的是:
如果在then里写了一个条件判断,返回不同的值,如:
then(res=>{
if(a)
return 1;
else
return 0;
}).then(res=>{
if(res == 1)
//....
else
//....
})
显然没有问题,因为hold住了所有的返回。那么如果把return 0 这一句去掉呢?后面会收到怎样的返回值?还是会被直接忽略?
经过测试后,如果有一个条件没有return,在下一个then里将收到undefined。这告诉我们,不要偷懒。