我有一张表,其中人员被保存了他们活跃的时间(以秒为单位)。
我想编写一个函数来收集另一个名为gather
的表中的总时间。
对于每一行,我正在检查gather
表中的条目是否存在。根据该结果,我进行插入或更新。
db.serialize(function() {
db.each("SELECT * from TEST", function(err, row) {
db.get("SELECT * from GATHER where name = " + row.name "", function(err, row) {
if(row === undefined || row === null){
var stmt = db.prepare("INSTER INTO gather (name, time) VALUE(?,?)");
stmt.run([name, seconds], function(error){
console.log('lastInsert ' + this.lastID);
});
stmt.finalize();
}else{
seconds += row.time;//increment time
var stmt = db.prepare("UPDATE gather SET time = ? WHERE name = ?");
stmt.run([seconds, row.name], function(error){
console.log('lastInsert ' + row.idProcessed);
});
stmt.finalize();
}
});
});
});
我遇到的问题是sqlite以异步方式运行。因此,虽然应更新行,但在gather
表中创建了多个条目。
同步运行此功能的正确方法是什么?我应该限制线路并每秒调用一次功能还是有智能的方式?
答案 0 :(得分:2)
您可以使用async。例如(但首先你应该阅读最后的最后笔记):
var async = require('async');
var data = {}
var yourFirstSelect() = function(callback){
//You do your first select
//...
db.get("SELECT * from TEST", function(err, row) {
if(row){
data.name = row.name;
data.otherInterestingAttribute = row.otherInterestingAttribute;
callback(err, data);
}else{
callback('Row is null');
}
})
//..
}
var yourSecondSelect() = function(data, callback){
//You do your second select
//...
db.get("SELECT * from GATHER where name = " + data.name "", function(err, row) { //Note that I'm using data instead of row
if(row){
data.seconds = row.seconds;
data.otherInterestingAttribute = row.otherInterestingAttribute;
callback(err, data);
}else{
callback('Row is null');
}
})
//..
}
var decide() = function(data, callback){
if (data.somethingExists) { //Do your validations
data.type = 'update';
callback(err, data);
} else {
data.type = 'insert';
callback(err, data);
}
}
var update() = function(data,callback){
if (data.type === 'update') {
//...
//Do your stuff in order to update
seconds += row.time;//increment time
var stmt = db.prepare("UPDATE gather SET time = ? WHERE name = ?");
stmt.run([seconds, row.name], function(error){
console.log('update ' + row.idProcessed);
});
stmt.finalize();
//...
} else {
callback(err,data);
}
}
var insert() = function(data,callback){
if (data.type === 'insert') {
//...
//Do your stuff in order to insert
var stmt = db.prepare("INSTER INTO gather (name, time) VALUE(?,?)");
stmt.run([data.name, data.seconds], function(error){
console.log('lastInsert ' + this.lastID);
callback(err,data);
});
stmt.finalize();
//...
} else {
callback(err,data);
}
}
var niceWorkflow = function(){
async.waterfall([
yourFirstSelect,
yourSecondSelect,
decide,
update,
insert
],
function (err, result) {
console.log('Done');
})
}
//and call your workflow
niceWorkflow();
当然,这不是100%正常工作的代码,我写的是为了让你看起来另一种方式来做你正在尝试的事情。许多变量,验证和更多只是示例,我故意忘记了db.each,以避免过于夸张和混淆你,并试图回答你的最后一个问题Is there a smarter way?
。
答案 1 :(得分:0)
您也可以使用Q library中的Q.all。 在所有承诺得到解决后,它将返回一个承诺。一个承诺失败,然后Q.all将被拒绝。