我的Phonegap应用程序检查设备(WebSQL)数据库中的代码。如果它找到了数据库和一条记录,它就打开页面,否则它调用函数addActivationCode(),该函数会显示一个表单,要求输入代码。
让我烦恼的部分是,当数据库存在并且记录在那里时,为什么底部的IF在txt . executesql之前被调用?
我已经在Chrome中使用警报进行了测试,并且在onDeviceReady函数完成之前肯定会调用IF。
当找到数据库时,var len被设置为一个计数。但是,首先测试IF,因此len==0并显示表单,然后运行txt . executesql并在表单上显示页面。
是否有可能以某种方式防止这种行为?
(这是web浏览器版本的代码。我正在使用JQuery):
$(document).on('pageinit','#home',function(){
$("#activation_form").hide();
checkDB();
function checkDB() {
db = window.openDatabase('TEST','1.0','test',2*1024);
var len = 0;
var act_code = "";
db.transaction( function (tx){
tx.executeSql('SELECT * FROM TEST',[],function(tx,results){
var i;
len = results.rows.length;
for (i = 0; i < len; i++){
act_code = results.rows.item(i).actcode;
}
build_page(act_code);
}, null);
if (len === 0){
addActivationCode();
}
});
}
});
为什么在text . executesql运行之前调用这个IF ?即使数据库存在,Var len也不会被设置。几秒钟后,txt . executesql运行,var len被设置为一个值,build_page被调用。
db.transaction()调用是一个异步调用,这意味着函数调用将立即返回作为参数传递的以异步模式运行的函数。
它将不等待作为参数传递的函数完成执行。
因此,IF语句在tx.()调用完成执行之前执行。同样的解释也适用于tx.()调用。tx调用是一个Async函数。您需要在function(tx,results){...}
tx.executeSql('SELECT * FROM TEST',[],function(tx,results){
var i;
len = results.rows.length;
if (len === 0){
addActivationCode();
} else {
for (i = 0; i < len; i++){
act_code = results.rows.item(i).actcode;
}
build_page(act_code);
}
}, null);
最后我重新组织了代码,这在Chrome中完美地工作:
function onDeviceReady() {
db = window.openDatabase('TEST','1.0','TEST',2*1024);
var len = 0;
var act_code = "";
db.transaction(findCode, onError1, addCode);
function findCode(tx){
tx.executeSql('SELECT * FROM TEST',[],loadPage,onError2);
}
function loadPage(tx,results){
len = results.rows.length;
for (i = 0; i < len; i++){
act_code = results.rows.item(i).actcode;
}
build_page(act_code);
}
function addCode(){
if(len==0){
addActivationCode();
}
}
}