简体   繁体   中英

JavaScript WebSQL Thread Locking Safety

So I have a Javascript Class that wraps and manages access to the WebSQL Database system.

the code for the class can be found: https://jsfiddle.net/dsct89kv/

now to test it I'm using

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());
  }

if I run all of these line by line one after another in the console it works perfectly but if I run the group it becomes thread locked on test.waitForBlockLift();

so that is defined as

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

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

the initial value of blocking = false when a query is called test.query it is set to true and once the transaction has completed and called the callback then set it back to false but for some reason when I call in a single line from the Console eg test.query("SELECT * FROM logs"); test.waitForBlockLift(); console.log(test.fetchRows()); test.query("SELECT * FROM logs"); test.waitForBlockLift(); console.log(test.fetchRows()); that does not happen the javascript engine works as I can still use the console. however, I can't access test and the tread appears to lock the whole point was to enable it to wait for the thread to unlock.

I must be doing something wrong but can't work out what

In the main thread of Javascript, this construct:

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

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

is an infinite loop. That's because the main execution path in Javascript is single threaded. So, while you're looping there in that single thread, nothing else can ever run. Therefore the blocking variable can never be changed, thus your loop runs forever. You can't do a wait loop like this in Javascript.

Instead, you have to use completion callbacks to know when asynchronous operations are done. You don't show any of your actual database code, but all database operations should have callbacks that will tell you when they are done. You will need to use those to know when operations are complete. You pass a callback and it will call you when things are done. This then allows other code to run while you are waiting for the callback function to be called.


Per your comments, in Javascript, you would not do this:

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

Instead, you would use a completion callback to do something like this:

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

Or, if you returned a promise from test.query() , you could code it like this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM