ちょっとヒントこれを試してみてください -
var numInserts = 0;
$.ajax({
url: myURL,
type: 'post',
data: 'tid=4',
dataType: 'json',
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('new_page_node_view - failed to retrieve page node');
console.log(JSON.stringify(XMLHttpRequest));
console.log(JSON.stringify(textStatus));
console.log(JSON.stringify(errorThrown));
},
success: function (data) {
numInserts = data.length; // num of inserts to expect (assumes data is in array of objects)
$.each(data, function (node_index,node_value) {
db.transaction(function(tx){
tx.executeSql("INSERT INTO 'tableA' (step, text) VALUES (?, ?)",[node_value.title, node_value.body],
function(tx, results){
numInserts--; // decrement 1 from expected num of inserts
if (numInserts == 0){
db.transaction(queryDB, errorCB, successCB);
}
},
function(tx, err){
console.log("insert error");
if (err){
console.log(err);
}
});
});
});
}
});
/Update - 上記のアプローチが必要な理由への回答。
queryDB
では、以下のように、$.each ループの後に AJAX 呼び出しの成功コールバックですぐに呼び出さない理由を疑問に思うかもしれません。
$.ajax({
url: myURL,
type: 'post',
data: 'tid=4',
dataType: 'json',
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('new_page_node_view - failed to retrieve page node');
console.log(JSON.stringify(XMLHttpRequest));
console.log(JSON.stringify(textStatus));
console.log(JSON.stringify(errorThrown));
},
success: function (data) {
$.each(data, function (node_index,node_value) {
db.transaction(function(tx){
tx.executeSql("INSERT INTO 'tableA' (step, text) VALUES (?, ?)",[node_value.title, node_value.body]);
});
});
db.transaction(queryDB, errorCB, successCB); // <-- the inserts could not all be finished when this gets called
}
});
JSON の結果から挿入するレコードが 1000 件あるとします。db.transaction(queryDB, errorCB, successCB);
これらの挿入は、AJAX 呼び出しが成功したときに終了しません。tx.executeSql
挿入がいつ終了したかを知るには、挿入に 成功コールバックを実装する必要があります。
上記の最初のアプローチで代わりに行ったことにより、関数を呼び出す前にすべての挿入を完全に完了することができますqueryDB
。にインラインの成功と失敗のコールバックを追加しましたtx.executeSql("INSERT INTO 'tableA' (step, text) VALUES (?, ?)",[node_value.title, node_value.body]);
。PhoneGap の WebSQL に対してこれを行うことを常にお勧めします (インラインである必要はありません)。
以前の仕事では、PhoneGap で広範な WebSQL トランザクションを実行しました。これには、JSON をループしてローカル データベース テーブルに書き込む作業が含まれていました。多くの挿入があり、ユーザーに通知する前に、またはあなたの場合は書き込まれたばかりのデータを引き出す前に、それらがすべて完全に完了したことを把握しようとすると、本当に難しい問題が発生します。
だから... 挿入の場合にあなたが学ぶトリックは -
- 実行が予想される挿入の数を数え、それを変数に格納します。
- 挿入の成功コールバックで、
tx.executeSql
期待する挿入数を保持する変数から 1 を引きます。
- 成功のコールバックで変数が 0 になると、
tx.executeSql
すべての挿入が完了したことがわかります。
インサート 1 個の簡単な例 -
// wrong approach here
db.transaction(function(tx){
tx.executeSql("INSERT INTO 'tableA' (step, text) VALUES (?, ?)",["foo", "bar"]);
// it will start the select query before the insert has completed
tx.executeSql("SELECT * FROM 'tableA'", [], querySuccess, errorCB);
});
// the right approach here
db.transaction(function(tx){
tx.executeSql("INSERT INTO 'tableA' (step, text) VALUES (?, ?)",["foo", "bar"], insertDone, insertFail);
});
function insertDone(tx, results){
// insert is done, now you can run the queryDB
tx.executeSql("SELECT * FROM 'tableA'", [], querySuccess, errorCB);
}
function insertFail(tx, err){
console.log("insert error");
if (err){
console.log(err);
}
}
queryDB
これが、AJAX 呼び出しの成功コールバックで を 実行するだけでなく、最初のアプローチを使用した理由を明確にするのに役立つことを願っています。
うまくいけば、これらすべてが将来誰かを助けるでしょう、笑。