2016-11-13 6 views
0

問題の概要:私はバックエンドにSQLデータベースを持っているプログラムに取り組んでいます。これは、npm SQLite3モジュールを使って話しています。私はサーバーに私のHTTP要求をするとき、私は別の投稿で私はres.sendその中の関数を実行する必要があると言われたので、関数が実行された後、それは関数から来たものを返します。簡単には十分ですか?しかし、私は非同期関数.all(API Doc here)で問題に遭遇しました。基本的に何が起こるのかというと、私は自分のデータベースを呼び出して、内部のすべてをdatabase.all内のオブジェクトに返しますが、database.allは非同期の関数であり、何も返されません。コールバック内にオブジェクトを送信するコールバックがありますが、そこから何をするか、またはコールバックが必要な場合でも私は何をするべきかわかりません。適切な配列のHTTP要求に応答する問題があります。 ExpressJで関数内から結果を送信する方法はありますか?

私の質問は:.all関数またはコールバック内のどこかからHTTP応答を送信できますか、または関数が呼び出された場所に配列を返す必要がありますか?私が言っていることを示すために以下のコードを書いてください。イベント(Github repo for refrence)

チェーン:

私は私のページが読み込まれる次のHTTPリクエストを送信するために、角度コントローラを設定している:

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

とサーバ(server.js)がそれを受け取ります

0:

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

test.jsという名前の別のファイルにloadWaitingList()関数を実行する:、私はこれを行います

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後に実行すると、後のrowで後私は値:AKAこの男、updateDB.Managerを呼び出し

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

rowdb.allにパラメータとして渡され、配列として返されました。db.allの外に宣言して結果を出力しましたが、db.allが非同期であるため、関数hasn 'まだ走っていない。

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

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

答えて

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); 
} 
+0

WOAH !!!あなたがそれをすることができるとは気づかなかった。私は今、それを見逃して非常に愚かだと思うが、大丈夫です!!!! :)それで、はるかに意味をなさない – Ryan

+0

+1は私より速く答える! @ Ryan、javascript/nodeを使い始めるのであれば、これらの本を強くお勧めします:https://github.com/getify/You-Dont-Know-JS。彼らは非常に良いと自由にオンラインで読むことができます。私はまた、これらの書籍でカバーされているPromises and Generatorsを調べることを強くお勧めします。 Javascriptは、非同期コードを処理するためのコールバックを使用していません。 –

1

あなたの関数にコールバックを渡すと、そのコールバックの内側でres.sendをトリガーする必要があります。ような何か:あなたの関数が完了するまで

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

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

このように、res.sendがトリガされていません。明らかに、このコードは非常に基本的です。私はエラーをチェックしていません。は、Managerメソッドに付属のcallbackを渡すだけです。おそらくこれをリファクタリングしてを完全に削除することができます。

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

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

これが役に立ちます。

関連する問題