1

indexedDB を使用してオフライン データを保存し、接続時にデータをアップロードしようとしています。次のコードでは、ループを使用して indexedDB からデータを読み取り、テーブル (ストア) 内の各レコード (オブジェクト) に対して JSON オブジェクトが作成され、PHP ファイルにポストされます。ただし、この indexedDB ループは 1 回しか実行されません。これは、JSON オブジェクトが非同期でサーバーに送信されたためですか?

var trans = LocalDB.indexedDB.db.transaction(storename, 
                                             IDBTransaction.READ_WRITE);
var store = trans.objectStore(storename);
var keyRange = IDBKeyRange.lowerBound(0);
var cursorRequest = store.openCursor(keyRange);

cursorRequest.onsuccess = function (e) {
    var result = e.target.result;
    var obj = new Object;
    obj.name = result.value.Name;
    obj.Date = result.value.Date;
    if (window.XMLHttpRequest)
        xmlhttp = new XMLHttpRequest();
    else
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    xmlhttp.onreadystatechange = function () {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
        {
            alert(xmlhttp.responseText);//problem: only shown once
            result.continue();
        }
    };
    xmlhttp.open("POST", "upload.php");
    xmlhttp.setRequestHeader("Content-type", "application/json", true);
    xmlhttp.send(JSON.stringify(obj));
};
cursorRequest.onerror = function (e) { alert("Error uploading"); };
4

1 に答える 1

1

コンソールでエラーを確認すると、おそらく次のように表示されます。

Uncaught Error: TransactionInactiveError

これは、Ajax リクエストが を遅らせていることが原因のようですresult.continue()。その間、トランザクションは明らかに非アクティブになり、カーソルで使用できなくなります。

result.continue()を の外に移動する必要がありますonreadystatechange

// ...
xmlhttp.send(JSON.stringify(obj));
result.continue();

S jax (同期)を選択することもできます。しかし、それは一般的に推奨されていません。


onsuccessまた、カーソルが完了したことを示すコールバックが追加で呼び出されることに注意してください。そのnull resultため、これをテストする必要があります。

cursorRequest.onsuccess = function (e) {
    var result = e.target.result;

    if (!result) {
        console.log('Done');
        return; // exit callback
    }

    // ...
};

Arrayこれを使用して、単一の Ajax リクエストでコレクション全体を送信することもできます。

var storedCollection = [];

cursorResult.onsuccess = function (e) {
    var result = e.target.result;

    if (result) {
        storedCollection.push(result.value);
        result.continue();
        return; // exit callback
    }

    // else: the cursor is "done"

    var xmlhttp = new XMLHttpRequest();
    // ...
    xml.send(JSON.stringify(storedCollection));
};

例: http://jsfiddle.net/CZBrd/ (コンソールを確認)

于 2013-07-30T03:11:28.047 に答える