1

バイナリ ファイルを取得して値を Web SQL データベースに挿入する単純なページを作成しようとしています。これは、データを挿入するために使用している関数です。

function bin2dbfunc()
{
    var result, n, aByte, byteStr;
    var i=0;
    var sql = new Array();

    result = fr.result;  //Input file

    for (n = 0; n < result.length; ++n) 
    {
        aByte = result.charCodeAt(n);
        byteStr = aByte.toString(16);
        if (byteStr.length < 2)
        {
            byteStr = "0" + byteStr;
        } //Format to add leading 0 for hex values

        //Looping through taking each byte read from file and adding to array

        //sql[i] = aByte;   //Value
        sql[i] = byteStr;   //String


        //When completed one row of database run single SQL insert statement with array contents
        if(i==15)
        {
            i=0;  //Clear counter for next row
            db.transaction(function (tx)
            {
                tx.executeSql('INSERT INTO binary_data VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [sql[0], sql[1], sql[2], sql[3], sql[4], sql[5], sql[6], sql[7], sql[8], sql[9], sql[10], sql[11], sql[12], sql[13], sql[14], sql[15]]);
            }, function (tx, err) {
                document.getElementById("result3").innerHTML += 'ERROR ';  //Display error message if SQL not run successfully
            });
        }
        else
        {
            i++;  //Otherwise increment counter
        }
    }
}

すべてのデバッグ メッセージを削除するためにコードを削除しましたが、基本的にはコードが実行されているように見えます。6 行分のデータを含むバイナリ ファイルを使用していますが、コードはデータの最後の行をデータベースに 6 回挿入します。誰かが私が間違っている場所を見つけることができますか?

4

1 に答える 1

0

変数は、JavaScript クロージャの値ではなく、参照によってキャプチャされます (これは、配列などのオブジェクトに当てはまりますが、プリミティブ値にも当てはまります)。これは、 に渡された関数が実行時にdb.transactionの現在の値を使用することを意味しsqlます。あなたの場合、それらは非同期で実行されるようです。したがって、sql一度の値を使用するbin2dbfuncと返されます(これが、データの最後の行になる理由を説明しています)。

sql正しいものが使用されていることを確認するために、の値をコピーする必要があります。

function transactionCallback(sql_) {
  var sql = sql_.slice(0); // copy
  return function(tx) {
    tx.executeSql(…, sql);
  };
}

db.transaction(transactionCallback(sql), …);

また

function transactionCallback(sql) {
  return function(tx) {
    tx.executeSql(…, sql);
  };
}

db.transaction(transactionCallback(sql), …);
sql = [];

sql後で の値は必要ないのでbin2dbfunc; この 2 番目のソリューションを使用すると、とiに基づくより洗練されたソリューションを削除して使用することもできます。pushlength

于 2012-11-07T10:06:44.097 に答える