JavaScript WebSQL线程锁定安全性

时间:2016-03-18 15:31:44

标签: javascript multithreading thread-safety

所以我有一个Javascript类来包装和管理对WebSQL数据库系统的访问。

可以找到该类的代码:https://jsfiddle.net/dsct89kv/

现在测试它我正在使用

function(){
    var test = new Database();
    test.open("test");
    test.query("CREATE TABLE `logs` (id INTEGER PRIMARY KEY, value VARCHAR)");
    test.query("SELECT * FROM `logs`"); 
    test.waitForBlockLift(); 
    console.log(test.fetchRows());
  }

如果我在控制台中一个接一个地逐行运行所有这些,它可以很好地工作但是如果我运行该组,它就会被test.waitForBlockLift();上的线程锁定

因此定义为

this.isBlocked = function(){ return blocking; };

this.waitForBlockLift = function(){
    var test = this.isBlocked();
    while(test){
        test = this.isBlocked();
    }
    return true;
}

调用查询时blocking = false的初始值test.query将其设置为true,一旦事务完成并调用回调,然后将其设置为false,但由于某种原因,我从控制台调用了一行,例如test.query("SELECT * FROM logs"); test.waitForBlockLift(); console.log(test.fetchRows()); javascript引擎没有发生,因为我仍然可以使用控制台。然而,我无法访问测试并且踏板似乎锁定整个点是为了让它等待线程解锁。

我一定是做错了什么但是找不到什么

1 个答案:

答案 0 :(得分:1)

在Javascript的主线程中,这个构造:

this.isBlocked = function(){ return blocking; };

while(test){
    test = this.isBlocked();
}

是一个无限循环。这是因为Javascript中的主要执行路径是单线程的。因此,当您在该单个线程中循环时,其他任何东西都无法运行。因此,blocking变量永远不会被更改,因此您的循环将永远运行。你不能在Javascript中做这样的等待循环。

相反,您必须使用完成回调来了解异步操作何时完成。您没有显示任何实际的数据库代码,但所有数据库操作都应该有回调,告诉您何时完成。您需要使用它们来了解操作何时完成。你传递一个回调,它会在事情发生时给你打电话。这样就可以在等待调用回调函数时运行其他代码。

根据您的评论,在Javascript中,您不会这样做:

test.query("SELECT * FROM logs");
console.log(test.fetchRows());

相反,您可以使用完成回调来执行以下操作:

test.query("SELECT * FROM logs", function(result) {
    console.log(test.fetchRows());
});

或者,如果您从test.query()返回了一个承诺,则可以这样编码:

test.query("SELECT * FROM logs").then(function(result) {
    console.log(test.fetchRows());
});