0

問題の概要: バックエンドに SQL データベースを持つプログラムに取り組んでおり、npm SQLite3 モジュールを使用して対話しています。サーバーに HTTP リクエストを行うと、別の投稿で、そのres.send中の関数を使用して関数を実行する必要があると言われました。そのため、関数が実行された後、関数から来たものは何でも返されます。簡単ですよね?しかし、その後、非同期関数.all (API Doc here)で問題が発生しました。基本的に何が起こるかというと、データベースを呼び出すと、内部のすべてが database.all 内のオブジェクトに返されますが、database.all は無効で何も返せない非同期関数です。コールバック内でオブジェクトを送信するコールバックがありますが、そこからどうすればよいのか、コールバックが必要なのかさえわかりません。

私の質問は、.all関数またはコールバック内のどこかから HTTP 応答を送信できますか、それとも関数が呼び出された場所に配列を返す必要があるかということです。以下のコードは、私が何を意味するかを示しています。

一連のイベント(参照用の Github リポジトリ) :

ページの読み込み時に次の HTTP リクエストを送信するように角度コントローラーをセットアップしました。

$http.get('/LoadWaitingList')
.then(function(response) {
    // alert("HTTP request set, getting data");
    console.log(response.data);
});

サーバー (server.js) がそれを受信したら、次のようにします。

app.get('/LoadWaitingList', function (req, res) {
  res.send(DatabaseFunction.loadWaitingList());
})

test.js という名前の別のファイルで loadWaitingList() 関数を実行します。

function  loadWaitingList() {
    var callbackFunction = function(err, response){
        var returnRow = response;
        return returnRow;
    }
    updateDB.Manager(callbackFunction);
}

これはupdateDB.Manager、別名この男を呼び出します:

Manager : function(callback){
    var fs = require("fs");
    var file = "./Source/Server/Data/DaycareDB.db";
    var exists = fs.existsSync(file);
    if (!exists) {
        throw new Error("File not Found");
    }
    var sqlite3 = require("sqlite3").verbose();
    var db = new sqlite3.Database(file);
    db.all("SELECT * FROM WaitingList", function(err, row) {
        if (err){
            callback(err);
            return;
        }
        // console.log(row[0].ChildName);                   
        callback(null, row);
        return;
    });
},

最後に、db.all実行後、私が求めている値を in で確認できますrowrowパラメータとして渡されdb.all、配列として返されるので、外部で宣言してdb.all渡してから結果を出力しようとしましたが、db.all非同期であるため、関数がまだ実行されていないため、常に空になります。

コールバックを実行し、コールバックが呼び出された後に (vscode デバッガーを使用して) オブジェクトをチェックするとreturnRow、データベースから適切なデータが含まれています。

入れられrow、最終的returnRowに応答として返されるデータを送信するにはどうすればよいですか? HTTP リクエストを別の方法で取得したときに最初の関数呼び出しを実行してres.sendから、コールバックなどから実行することは可能ですか?

4

2 に答える 2

1

コールバックを確認する必要があります。

app.get('/LoadWaitingList', function (req, res) {
  DatabaseFunction.loadWaitingList(function(err,data){
    if(err) {
      // handle the error here
    }
    // send the data
    res.send(data);
  }
});

ここloadWaitingList()で、標準のエラー ファースト コールバックをパラメーターとして受け取る必要があります。このコールバックは、実行される場所に渡さupdateDB.Manager()れます。

function loadWaitingList(callback) {
  updateDB.Manager(callback);
}
于 2016-11-13T06:09:18.907 に答える
1

loadWaitingListコールバックを関数に渡し、そのコールバック内からトリガーする必要がありres.sendます。何かのようなもの:

app.get('/LoadWaitingList', function (req, res) {
  DatabaseFunction.loadWaitingList(function(err, response) {
    res.send(response);
  });
});

function loadWaitingList(callback) {
  updateDB.Manager(callback);
}

この方法では、関数が完了res.sendするまでトリガーされません。loadWaitingList明らかに、このコードは非常に基本的です。私はエラーをチェックしておらず、提供されたものをメソッドにloadWaitingList渡しているだけです。おそらくこれをリファクタリングして完全に削除できます。callbackManagerloadWaitingList

app.get('/LoadWaitingList', function (req, res) {
  updateDB.Manager(function(err, response) {
    res.send(response);
  });
});

非同期で実行したいコードはすべて、コールバック内にある必要があることを覚えておいてください。元のコードのres.sendはコールバック内になかったため、すぐに実行されました。loadWaitingListしたがって、値を返す前に完了していました。

お役に立てれば。

于 2016-11-13T06:12:16.657 に答える