2

プロセス1を試している間、失敗します。

キャッチされないエラー:INVALID_STATE_ERR:ファイル:/// android_asset / www / library / custom.js:39のDOM例外11

しかし、私がプロセス2を試しているときは、それで問題ありません。

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")');
}
4

3 に答える 3

2

私は.ajax()を使用し、async:falseを追加してこの問題を解決しました。

$ .ajax({type: "POST"、url:myurl、dataType: "xml"、 async:false、 success:function(xml){

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

                            tx.executeSql('INSERT INTO ORDERS (id, client_ID, status) VALUES ('+ idord2 +', 4, "done" )');
                        });         
                    }
                });
于 2012-09-21T19:02:55.963 に答える
2

他の回答の1つは機能しますが、同じ問題が発生したため、さらに詳しく説明したいと思います。その回答には、OPの場合と同じように機能しない理由が記載されていません。

Web SQLでトランザクションを作成する場合、トランザクション処理は、トランザクションにキューに入れられたステートメントがある限り存続します。トランザクション内のステートメントのパイプラインが枯渇するとすぐに、エンジンはトランザクションを閉じます(コミットします)。アイデアは、function(tx) { ... }コールバックが実行されるとき、

  1. 必要なすべてのステートメントを実行します。executeSqlは非同期であるため、ステートメントがまだ実行されていなくてもすぐに戻ります。
  2. 制御をWebSQLエンジンに戻します。

この時点で、エンジンはキューに入れられたステートメントがあることを認識し、トランザクションを閉じる前にそれらを実行して完了します。あなたの場合、何が起こるかはこれです:

  1. 2回呼び出すとexecuteSql、2つのステートメントがキューに入れられます。
  2. あなたはajaxを通して何かを要求します。
  3. あなたが戻る

エンジンは、キューに入れられた2つのステートメントを実行します。ajaxリクエストも非同期で実行されていますが、低速のネットワークにアクセスする必要があるため、まだ完了していない可能性があります。この時点で、ステートメントキューは空になり、Web SQLエンジンは、トランザクションをコミットして閉じる時間であると判断します。後で別の声明が来ることを知る方法はありません!ajax呼び出しが戻って実行を試みるまでにINSERT INTO locations、手遅れになり、トランザクションはすでに閉じられています。

2つの主な解決策があります。

  • コールバック内の1つのトランザクションですべて(、、、DROPおよびCREATEすべて)を実行します。INSERTgetJSON

    これが私がお勧めするものです。テーブルを作成する前にajaxリクエストが完了するまで待つことは、アプリケーションの要件と互換性がある可能性が非常に高いと思います。

  • 他の回答で説明されているように、ajaxリクエストを同期的に実行します。

    私はそれをお勧めしません。JavaScriptでの非同期プログラミングは良いことです。

ちなみに、この問題を探していると、基本的に同じ答えの別の質問を見つけたので、同じ答えを書きましたが、そこにはもう少し詳細があります。SOでは回答のコピーと貼り付けが推奨されていないことは知っていますが、どちらかの質問を参照する将来のユーザーが回答を読めるようにしたかったのです。私はこれを1つのコミュニティウィキにしました。大丈夫だといいのですが。

于 2014-11-27T10:28:24.277 に答える
1

dbの操作は、devicereadyイベントの後に実行する必要があります。完全な例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);
    }
....
于 2012-09-04T23:02:20.990 に答える