1

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

4

1 回答 1

1

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

是的。通过将同步for循环与异步循环getResource()insert().

循环并行启动所有 20 轮,在实际插入之前,它们都在同时寻找重复项。他们都发现他们的结果集是空的,所以他们每个人都插入。

您可能希望使用异步迭代器,例如async's timesSeries(),因此每一轮都会延迟到之前的那些迭代完成。

async.timesSeries(20, function (i, done) {
    addResource("url", "type", function (id) {
        // ...
        done(null);
    });
});
于 2013-08-30T20:29:21.277 回答