【问题标题】:HTML5 WebSQL: how to know when a db transaction finishes?HTML5 WebSQL:如何知道数据库事务何时完成?
【发布时间】:2011-09-30 08:13:27
【问题描述】:

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

如何拦截 databaseSync() 函数的结束? 我想要做的是显示警报或更好的 ajax spinner gif,以便在同步完成时通知用户。

非常感谢您的帮助, 哎哟!

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 都已被调用。 +1 对于任何有很好的写作方式的人。

标签: jquery database html web-sql


【解决方案1】:

好的,这是我的第五次修订,但我喜欢这个问题并且我不断提出更好的想法。这个使用jquery deferred objects,我认为它最终涵盖了所有情况并按其应有的方式工作。

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 函数作为回调函数执行,然后这应该适合您。我希望你觉得这很有用。

【讨论】:

  • 我想你已经把 tableInsert 和 insertTable 混在一起了。
  • @JeffHutchins 将事务移到 each 之外是否有意义?我使用了与您类似的系统,但是当使用事务为每个插入批量插入 1000 行时,确实减慢了进程
  • 如果您将事务置于循环之外,那么您对跟踪 Deferreds 的全部需求就会消失。要么所有的 executeSql 语句都会通过,要么没有。您只需要监控事务的成功或错误回调。另外它会更快。
【解决方案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。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多