Phonegap:INVALID_STATE_ERR:DOM异常11

时间:2012-09-04 13:53:07

标签: database cordova

当我正在尝试处理过程时,它失败了:

  

未捕获错误:INVALID_STATE_ERR:文件中的DOM异常11:///android_asset/www/library/custom.js:39

但是当我尝试第二步时,它很好。

var db = window.openDatabase("Pemberton", "1.0", "Pemberton Stay App", 200000);
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
    db.transaction(populateDB, errorCB, successCB);
}

流程1:

function populateDB(tx) {
    tx.executeSql('DROP TABLE IF EXISTS eat');
    tx.executeSql('CREATE TABLE IF NOT EXISTS eat (id, image, title)');
    var queries = new Array();
    $.getJSON( serviceURL + 'category-list.php?cid=1&p=?', function(data) {
        var results = data.items;
        $.each(results,function(index,record){
            if( record.id != undefined )
                tx.executeSql('INSERT INTO eat (id, image, title) VALUES ("'+record.id+'","'+record.image+'","'+record.title+'")');
        });

    });    
}

流程2:

function populateDB(tx) 
{
    tx.executeSql('INSERT INTO eat (id, image, title) VALUES (2,"one.jkd","OneFirst")');
    tx.executeSql('INSERT INTO eat (id, image, title) VALUES (2, "two.png","Second")');
    tx.executeSql('INSERT INTO eat (id, image, title) VALUES (3, "thr.png","Third")');
    tx.executeSql('INSERT INTO eat (id, image, title) VALUES (4, "fou.png","Fourth")');
    tx.executeSql('INSERT INTO eat (id, image, title) VALUES (5, "fiv.png","Fifth")');
}

3 个答案:

答案 0 :(得分:2)

我使用.ajax()并通过添加 async:false ;

解决了这个问题
  

$。AJAX({                           类型:“POST”,                           url:myurl,                           dataType:“xml”,                            async:false,                           成功:function(xml){

                    $(xml).find('articles').each(
                        function ()
                        {

                            tx.executeSql('INSERT INTO ORDERS (id, client_ID, status) VALUES ('+ idord2 +', 4, "done" )');
                        });         
                    }
                });

答案 1 :(得分:2)

虽然one of the other answers works,但我想扩展它,因为我遇到了同样的问题而且答案并没有说为什么它不能作为OP工作有它。

在Web SQL中创建事务时,只有there are any statements queued up in the transaction,事务处理才会保持活动状态。一旦事务中的语句管道干涸,引擎就会关闭(提交)事务。这个想法是当function(tx) { ... }回调运行时,

  1. 它执行所需的所有语句。 executeSql是异步的,因此即使语句尚未执行,它也会立即返回。
  2. 它将控制权返回给Web SQL引擎。
  3. 此时引擎注意到有一些语句排队并在关闭事务之前将它们运行完成。在你的情况下,会发生什么:

    1. 您拨打executeSql两次以排队两个语句。
    2. 您通过ajax请求。
    3. 你回来了
    4. 引擎运行已排队的两个语句。 ajax请求也是异步运行的,但它必须访问速度很慢的网络,因此可能还没有完成。此时,语句队列为空,Web SQL引擎决定提交和关闭事务的时间!它无法知道将来会有另一个声明!当ajax调用返回并且它尝试执行INSERT INTO locations时,为时已晚,该事务已经关闭。

      主要有两种解决方案:

      • DROP回调中的一个交易中执行所有操作(CREATEINSERT和所有getJSON)。

        这是我推荐的。我认为,在创建表之前等待ajax请求完成后,很可能会与您的应用程序要求兼容。

      • 按照其他答案中的说明同步执行ajax请求。

        我不推荐。 JavaScript中的异步编程是一个好的事物。

      顺便说一句,在搜索这个问题时,我发现this other question基本上有相同的答案,所以我写了the same answer,但那里有更多细节。我知道那份副本&不鼓励粘贴答案,但我想确保未来的用户咨询任何一个问题都可以阅读答案。我做了这个社区维基。我希望没问题。

答案 2 :(得分:1)

必须在deviceready事件之后执行db操作,请参阅完整示例http://docs.phonegap.com/en/1.2.0/phonegap_storage_storage.md.html#SQLTransaction

....
// Wait for PhoneGap to load
    //
    document.addEventListener("deviceready", onDeviceReady, false);

    // PhoneGap is ready
    //
    function onDeviceReady() {
        var db = window.openDatabase("Database", "1.0", "PhoneGap Demo", 200000);
        db.transaction(populateDB, errorCB, successCB);
    }
....