Node.js 的异步数据库问题
Asynchronous Database Problems with Node.js
我正在尝试查询一个数据库,运行在节点服务器上查询数据库而不使用 sqlite3,以检查数据库中是否有元素。在发现此元素是否存在后,它将继续使用此信息访问不同的 table。
var username;
checkSessionID(usersSessionID, function(temp) {
username = temp[0].username;
});
var db = new sql.Database("Pete's FCRs.db");
var ps = db.prepare("select * from users where username = ?", errorFunc);
ps.all(username, function(err, rows) {
if (err) throw err;
console.log(rows);
});
ps.finalize();
db.close();
function checkSessionID(sessionID, callback) {
var db = new sql.Database("Pete's FCRs.db");
var ps = db.prepare("select * from sessionIDs where sessionID = ?", errorFunc);
ps.all(sessionID, function(err, rows) {
if (err) throw err;
callback(rows);
});
ps.finalize();
db.close();
}
("test: " + sessionDetails);
1) 我运行 checkSessionID 检查sessionID 是否在数据库中,在sessionIDs table 中。
2) 接下来,它调用回调函数,以存储与会话ID关联的用户名。
但是,由于回调是异步的,我在 "username" 更新之前访问数据库。
要尝试解决此问题,无法在回调函数内移动数据库查询,因为这会导致错误,因为数据库已锁定。
非常感谢您的帮助。
编辑
通过将 db 声明为全局变量并在所有进程完成后关闭它来设法解决它。
通常在编写异步代码时,您需要在回调中移动代码,否则它会立即触发:
var db = new sql.Database("Pete's FCRs.db");
var ps = db.prepare("select * from users where username = ?", errorFunc);
ps.all(username, function(err, rows) {
if (err) throw err;
console.log(rows);
ps.finalize();
db.close();
});
请记住,您的代码是乱序执行的,而不是一行接着一行。
我发现使用像 Bluebird 这样的 promise 库有助于大大简化此代码并使其更易于理解。 Promises 可能需要一些时间来吸收,它们是一个新概念,但是一旦您了解它们的工作原理,事情链就会好很多。
此代码的承诺版本大致如下:
ps.all(username)
.then(function(rows) {
console.log(rows);
})
.then(function() {
return ps.finalize();
})
.then(function() {
return db.close();
})
错误捕获是自动完成的,如果需要,可以添加特殊的处理程序。
我正在尝试查询一个数据库,运行在节点服务器上查询数据库而不使用 sqlite3,以检查数据库中是否有元素。在发现此元素是否存在后,它将继续使用此信息访问不同的 table。
var username;
checkSessionID(usersSessionID, function(temp) {
username = temp[0].username;
});
var db = new sql.Database("Pete's FCRs.db");
var ps = db.prepare("select * from users where username = ?", errorFunc);
ps.all(username, function(err, rows) {
if (err) throw err;
console.log(rows);
});
ps.finalize();
db.close();
function checkSessionID(sessionID, callback) {
var db = new sql.Database("Pete's FCRs.db");
var ps = db.prepare("select * from sessionIDs where sessionID = ?", errorFunc);
ps.all(sessionID, function(err, rows) {
if (err) throw err;
callback(rows);
});
ps.finalize();
db.close();
}
("test: " + sessionDetails);
1) 我运行 checkSessionID 检查sessionID 是否在数据库中,在sessionIDs table 中。 2) 接下来,它调用回调函数,以存储与会话ID关联的用户名。
但是,由于回调是异步的,我在 "username" 更新之前访问数据库。
要尝试解决此问题,无法在回调函数内移动数据库查询,因为这会导致错误,因为数据库已锁定。
非常感谢您的帮助。
编辑
通过将 db 声明为全局变量并在所有进程完成后关闭它来设法解决它。
通常在编写异步代码时,您需要在回调中移动代码,否则它会立即触发:
var db = new sql.Database("Pete's FCRs.db");
var ps = db.prepare("select * from users where username = ?", errorFunc);
ps.all(username, function(err, rows) {
if (err) throw err;
console.log(rows);
ps.finalize();
db.close();
});
请记住,您的代码是乱序执行的,而不是一行接着一行。
我发现使用像 Bluebird 这样的 promise 库有助于大大简化此代码并使其更易于理解。 Promises 可能需要一些时间来吸收,它们是一个新概念,但是一旦您了解它们的工作原理,事情链就会好很多。
此代码的承诺版本大致如下:
ps.all(username)
.then(function(rows) {
console.log(rows);
})
.then(function() {
return ps.finalize();
})
.then(function() {
return db.close();
})
错误捕获是自动完成的,如果需要,可以添加特殊的处理程序。