HTML5 WebSQL:如何知道数据库事务何时完成?

12

我有以下代码,用于获取JSON记录集并在客户端Web SQL存储中的三个不同表中插入一些数据。

如何拦截databaseSync()函数的结束? 我想要做的是显示一个警报或更好的是一个Ajax旋转图标,以便在同步完成时通知用户。

非常感谢您的帮助, 再见!

function databaseSync() {

        // table one
        $.getJSON("http://192.168.1.40:8888/iOS/mobilesrv/index.php?ACT=one", function(json) {
            $.each(json.results, function(i, res) {
                db.transaction(function(tx) {
                    tx.executeSql("INSERT INTO table1 (A, B, C, D) VALUES (?,?,?,?) ", [res.A, res.B, res.C, res.D], onSuccess, onError);
                });
            });
        });

        // table two
        $.getJSON("http://192.168.1.40:8888/iOS/mobilesrv/index.php?ACT=two", function(json) {
            $.each(json.results, function(i, res) {
                db.transaction(function(tx) {
                    tx.executeSql("INSERT INTO table1 (A, B, C, D) VALUES (?,?,?,?) ", [res.A, res.B, res.C, res.D], onSuccess, onError);
                });
            });
        });

        // table three
        $.getJSON("http://192.168.1.40:8888/iOS/mobilesrv/index.php?ACT=three", function(json) {
            $.each(json.results, function(i, res) {
                db.transaction(function(tx) {
                    tx.executeSql("INSERT INTO table1 (A, B, C, D) VALUES (?,?,?,?) ", [res.A, res.B, res.C, res.D], onSuccess, onError);
                });
            });
        });


    }

+1 你需要等待所有的 onSuccessonError 被调用后才能继续执行。如果有更好的表达方式,再加一分。 - Thilo
2个回答

13

好的,这是我的第五次修订,但我喜欢这个问题,也一直有更好的想法。这个方案使用了jQuery延迟对象,我认为它最终涵盖了所有情况,并且按照预期工作。

function tableInsert(url) {
    var dfd = $.Deferred();
    var arr = [];
    $.getJSON(url, function(json) {
        $.each(json.results, function(i, res) {
            var dfd = $.Deferred();
            arr.push(dfd.promise()); 
            db.transaction(function(tx) {
                tx.executeSql(
                    "INSERT INTO table1 (A, B, C, D) VALUES (?,?,?,?) ", 
                    [res.A, res.B, res.C, res.D], 
                    function(){
                        onSuccess(dfd.resolve);
                    }, 
                    function(){
                        onError(dfd.resolve);
                    }
                );
            });
        });
        $.when.apply(this, arr).then(dfd.resolve);
    });
    return dfd.promise();
}

function databaseSync() {

    $.when( tableInsert("http://192.168.1.40:8888/iOS/mobilesrv/index.php?ACT=one"),
            tableInsert("http://192.168.1.40:8888/iOS/mobilesrv/index.php?ACT=two"), 
            tableInsert("http://192.168.1.40:8888/iOS/mobilesrv/index.php?ACT=three"))
        .then(function(){
            console.log( 'All processing complete' );
        });
}

为使这个方法生效,你需要将 onSuccess 和 onError 执行 resolve 函数作为回调函数并在执行它们自己的任务后再执行 resolve 函数,然后这个方法应该就能够正常工作了。希望这对你有所帮助。


我认为您混淆了tableInsert和insertTable。 - Phillip Senn
1
@JeffHutchins,把交易移出循环外面不是更合理吗?我用了一个类似你的系统,但每次插入都使用交易,当批量插入1000行时,这真的会减慢进程。 - Jon Wells
如果您将事务放在循环外面,那么您跟踪延迟对象的整个需求就会消失。所有 executeSql 语句都要么全部执行成功,要么全部失败。只需要监控事务的成功或错误回调即可。而且速度会更快。 - oligofren

-2

或者,您可以使用一个事务进行批量插入,并使用回调函数来获取有关事务完成的通知

function doSync(){
  databaseSync(function(){
    console.log('database sync is completed')
  });
}

function databaseSync(onTrxSuccess) {
  db.transaction(function(tx) {
  // table one
  $.getJSON("http://192.168.1.40:8888/iOS/mobilesrv/index.php?ACT=one", function(json) {
        $.each(json.results, function(i, res) {                
                tx.executeSql("INSERT INTO table1 (A, B, C, D) VALUES (?,?,?,?) ", [res.A, res.B, res.C, res.D], onSuccess, onError);
            });
        });


    // table two
    $.getJSON("http://192.168.1.40:8888/iOS/mobilesrv/index.php?ACT=two", function(json) {
        $.each(json.results, function(i, res) {
                tx.executeSql("INSERT INTO table1 (A, B, C, D) VALUES (?,?,?,?) ", [res.A, res.B, res.C, res.D], onSuccess, onError);
            });
    });

    // table three
    $.getJSON("http://192.168.1.40:8888/iOS/mobilesrv/index.php?ACT=three", function(json) {
        $.each(json.results, function(i, res) {
                tx.executeSql("INSERT INTO table1 (A, B, C, D) VALUES (?,?,?,?) ", [res.A, res.B, res.C, res.D], onSuccess, onError);
            });
        });
    }, null, onTrxSuccess);


}

不能保证插入操作是顺序执行的,因此可能会丢失2/3的数据。 - oligofren

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接