与另一个事务内部的同步WebSQL事务

时间:2014-08-24 15:01:35

标签: javascript sql transactions web-sql synchronous

我知道我无法同步检索事务的值。我读过另一种方法是回调函数。但我无法做到这一点..这里是我在函数中插入第二个事务的片段。

for(...){
    db.transaction(function(tx) {
            tx.executeSql('SELECT ...', function(tx, results) {
                ...
                ...
                weight = weightRetrieve(month, year);
                calories = 0.9 * km * weighta;
            });
update+=xxx+calories+yyy;
} //for end

 $("#form").html(update).trigger('create'); 

这是第二个功能:

function weightRetrieve(month, year) {
    db.transaction(function(tx) {
                tx.executeSql('SELECT weight,day,  ......etc) {

weight=results.rows.item(i).weight;
return weight;
}
}

我删除了很多代码,但我遇到的唯一问题是我无法从第二个函数中检索权重,无论是这样还是在第一个事务中,如果工作异步

如果我用localStorage存储值,这将是不好的编程吗?

1 个答案:

答案 0 :(得分:2)

作为一般规则,如果您正在使用异步调用,那么尝试“返回”某个值并不会对您有所帮助。外部函数通常在内部异步函数将任何数据放入变量之前完成执行并返回变量,因此最终返回一个空变量。另外在你的情况下,你的“return”是从你传递给db.transaction而不是weightRetreive的匿名函数返回的。

你需要传入一个回调函数作为参数,然后一旦你拥有它就调用该回调函数。

例如:

function weightRetrieve(month, year, onSuccess) {
    db.transaction(function(tx) {
        tx.executeSql('SELECT weight,day,  ......etc', [], function(tx, results) {

            weight=results.rows.item(i).weight;
            onSuccess(weight);

        });
    });
}

注意添加参数“onSuccess”作为回调函数。

因为这一切都在for循环中,所以你需要为每次迭代提供完成的机会,并在继续之前将其“卡路里”计算添加到最终累计值。要做到这一点,你可以创建一个函数,在每次迭代结束时调用,它跟踪它被调用的次数,并将它与你在执行最终代码之前循环的事物的长度进行比较: / p>

var updateFinalValue = (function() {

    var numCalls = 0; // number of times the function has been called
    var totalIterations = thingYouLoopOver.length; // number of times the for loop will run
    var finalValue = 0; // total of all your "calories" calculations

    return function(additionalValue) {

        finalValue += additionalValue;

        if(++numCalls == totalIterations ) {

            document.getElementById("totalCalories").value = finalValue;
            doSomethingWithFinalValue(finalValue);
            // etc
        }
    };
})();

如果您对javascript不太熟悉,语法可能看起来有点奇怪,但是当您调用“updateFinalValue”时,返回的内部函数会被执行。外部函数立即被评估(注意结尾的“();” - 我们正在调用外部函数)并且仅用于为内部函数提供范围。这被称为“闭包”,除其他外,它是封装变量的好方法,而不是必须使它们成为全局变量。

然后您将按如下方式使用它:

for(...) {
    db.transaction(function(tx) {
        tx.executeSql('SELECT ...', [], function(tx, results) {
            ...
            ...
            weightRetrieve(month, year, function(weight) {

                var calories = 0.9 * km * weight;
                updateFinalValue(calories);

            });
        });
    });
}