-1

要素がデータベース内にあるかどうかを確認するために、sqlite3 を使用して Express なしでノード サーバー上で実行されているデータベースにクエリを実行しようとしています。この要素が存在するかどうかを確認すると、この情報を使用して別のテーブルにアクセスします。

var username;
checkSessionID(usersSessionID, function(temp) {
    username = temp[0].username;
});
var db = new sql.Database("Pete's FCRs.db");
var ps = db.prepare("select * from users where username = ?", errorFunc);
ps.all(username, function(err, rows) {
    if (err) throw err;
    console.log(rows);
});
ps.finalize();
db.close();

function checkSessionID(sessionID, callback) {
var db = new sql.Database("Pete's FCRs.db");
var ps = db.prepare("select * from sessionIDs where sessionID = ?", errorFunc);
ps.all(sessionID, function(err, rows) {
    if (err) throw err;
    callback(rows);
});
ps.finalize();
db.close();
}

("test: " + sessionDetails);

1) checkSessionID を実行して、sessionID がデータベースの sessionIDs テーブルにあるかどうかを確認します。2) 次に、コールバック関数を呼び出して、セッション ID に関連付けられたユーザー名を保存します。

ただし、コールバックが非同期であるため、「ユーザー名」が更新される前にデータベースにアクセスしています。

これを解決するために、データベース クエリをコールバック関数内に移動することはできません。データベースがロックされているため、エラーが発生するためです。

助けてくれてありがとう。

編集

db をグローバル変数として宣言し、すべてのプロセスが完了した後に閉じることで、なんとか解決しました。

4

1 に答える 1

0

通常、非同期コードを記述する場合は、コードをコールバック内に移動する必要があります。そうしないと、すぐに起動します。

var db = new sql.Database("Pete's FCRs.db");
var ps = db.prepare("select * from users where username = ?", errorFunc);

ps.all(username, function(err, rows) {
  if (err) throw err;
  console.log(rows);

  ps.finalize();
  db.close();
});

コードが順不同で実行されていることに注意してください。

Bluebirdのような promise ライブラリを使用すると、このコードが大幅に簡素化され、追跡が容易になることがわかりました。Promise は新しい概念であるため、理解するのに少し時間がかかる場合があります。

このコードの promise バージョンは、おおよそ次のようになります。

ps.all(username)
  .then(function(rows) {
     console.log(rows);
  })
  .then(function() {
    return ps.finalize();
  })
  .then(function() {
    return db.close();
  })

エラーのキャッチは自動的に行われ、必要に応じて特別なハンドラーを追加することができます。

于 2015-04-14T19:45:10.840 に答える