JavaScript Web SQL回调插入(如果不存在)

JavaScript Web SQL callbacks insert if not exists

本文关键字:如果 如果不 不存在 插入 Web SQL 回调 JavaScript      更新时间:2023-09-26

我使用这个插入函数在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"检查都在创建之前通过。那么,有没有办法阻止这种情况的发生呢?当我对数据库施加约束时,当违反约束时,代码就会停止运行,这是我不希望发生的。

我怀疑回调执行的延迟使得所有"===0"检查都在创建之前通过。

是的。通过将同步for循环与异步getResource()insert()混合,在每一轮之间都有一个竞争条件。

循环并行开始所有20轮,在实际插入之前,所有轮都在同一时间寻找重复。他们都发现自己的结果集是空的,所以他们各自插入。

您可能想要使用异步迭代器,例如asynctimesSeries(),因此每一轮都会延迟到完成之前。

async.timesSeries(20, function (i, done) {
    addResource("url", "type", function (id) {
        // ...
        done(null);
    });
});