我正在使用此插入函数在 for 循环中将资源插入到数据库中。 我首先查询数据库中是否已经有类似的资源。如果是这样,我们不需要重新创建它。
for(var i = 0; i < 20; i++){
!function(i){
addResource("url", "type", ...)
}(i) // for local variable with callback
}
function addResource(url, type, callback){
getResource({"url":url}, function(tx, result){
console.log(result.rows.length, result.rows.length===1);
if(result.rows.length===0){ //didn't exist yet -> create it && return id
insertResource(url, type, function(tx, r){
callback(r.insertId);
});
} else if(result.rows.length===1){ //already exist -> return id
callback(result.rows.item(0).id);
} else { //should not happen -> error
console.error("addResource: Non unique identifier");
}
});
}
function insertResource(url, type, callback){
var query = "INSERT INTO resource(url, type) VALUES (?, ?);";
insert(query, [url, type], callback);
}
但是,当我运行此代码时,相同的资源会添加 20 次,而不是仅添加一次。我怀疑回调执行的延迟使得所有“===0”检查在创建它们之前就通过了。 那么有没有办法阻止这种情况发生呢?当我对数据库施加约束时,当违反约束时代码就会停止运行,这是我不希望发生的情况。
最佳答案
I suspect that the delay on the execution of the callbacks makes it so that all the "===0" checks pass before any of them are created.
是的。通过将同步 for
循环与异步 getResource()
和 insert()
混合在一起,您可以在每轮之间设置竞争条件。
该循环并行启动所有 20 轮,在实际插入任何重复项之前,它们都会同时查找重复项。他们都发现他们的结果集是空的,所以他们各自插入。
您可能想要使用异步迭代器,例如 async
的timesSeries()
,因此每轮都会延迟,直到之前的轮完成为止。
async.timesSeries(20, function (i, done) {
addResource("url", "type", function (id) {
// ...
done(null);
});
});
关于JavaScript Web SQL 回调如果不存在则插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18539974/