質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Q&A

解決済

1回答

1391閲覧

Node.jsでのDBデータ取得を同期処理にしたい

aiai8976

総合スコア112

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

0グッド

1クリップ

投稿2019/09/06 02:30

編集2019/09/06 02:32

前提・実現したいこと

Node.jsでwebサーバをつくっています。
そのひとつの処理にDBデータを検索して取得する部分があるのですが、Node.jsは非同期処理なので処理が終わる前に次に進んでしまい、空のまま渡してしまってエラーが起きているという状況です。
そこでその処理が終わったあとに次にすすむよう同期処理にしたいのですが、うまくいきません。
以下のサイトを見ながらPromiseを使おうとしましたが、同期処理できない状況です。
https://blog.honjala.net/entry/2018/08/08/022027
何か解決策があればコメントお願いします。

発生している問題・エラーメッセージ

$ node webServer.js Server running Connected correctly to server / /js/three.js-master/build/three.min.js /js/OrbitControls.js /css/index.css /get_value レスポンス undefined TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be one of type string or Buffer. Received type undefined at write_ (_http_outgoing.js:595:11) at ServerResponse.write (_http_outgoing.js:567:10) at Object.getValue (/home/hasegawa/デスクトップ/akiyama/Node.js/webServer.js:137:17) at process._tickCallback (internal/process/next_tick.js:68:7) /favicon.ico はいった

該当のソースコード

//DB接続準備 const MongoClient = require('mongodb').MongoClient; const url_db = 'mongodb://localhost:27017'; // Connection URL const dbName = 'study'; // Database Name const client = new MongoClient(url_db, { useNewUrlParser: true }); const assert = require('assert'); var collection; //var value; // Use connect method to connect to the server client.connect(function (err) { assert.equal(null, err); console.log("Connected correctly to server"); const db = client.db(dbName); // Get the documents collection collection = db.collection('user'); /*collection.find({}).sort({ time: -1 }).toArray(function (err, docs) { console.log("はいった"); for (var doc of docs) { value = doc; break; } //value = docs; });*/ }); function asyncFunc() { return new Promise((resolve) => { // ...何かしらの時間がかかる処理... let result; collection.find({}).sort({ time: -1 }).toArray(function (err, docs) { console.log("はいった"); for (let doc of docs) { result = doc; break; } //value = docs; }); process.on('unhandledRejection', console.dir) resolve(result); }); } // http.createServerがrequestされたら、(イベントハンドラ) server.on('request', function (req, res) { // Responseオブジェクトを作成し、その中に必要な処理を書いていき、条件によって対応させる var Response = { "renderHTML": function () { }, "getThree": function () { }, "getOrbit": function () { }, "getCSS": function () { }, "getValue": async function () { let value = await asyncFunc(); //client.close(); // HTTPレスポンスヘッダを出力する res.writeHead(200, { 'content-Type': 'text/html', 'Access-Control-Allow-Origin': '*' }); console.log("レスポンス"); //console.log(result); console.log(value); // HTTPレスポンスボディを出力する res.write(JSON.stringify(value)); res.end(); }, "postData": function () { }; // urlのpathをuriに代入 var uri = url.parse(req.url).pathname; console.log(uri); // URIで行う処理を分岐させる if (uri === "/") { // URLが「IPアドレス/:1234/」の場合、"renderHTML"の処理を行う Response["renderHTML"](); return; } else if (uri === "/js/three.js-master/build/three.min.js") { // URLが「IPアドレス/:1234/js/three.js-master/build/three.min.js」の場合、"getThree"の処理を行う Response["getThree"](); return; } else if (uri === "/js/OrbitControls.js") { // URLが「IPアドレス/:1234/js/OrbitControls.js」の場合、"getOrbit"の処理を行う Response["getOrbit"](); return; } else if (uri === "/css/index.css") { Response["getCSS"](); return; } else if (uri === "/get_value") { // URLが「IPアドレス/:1234/get_value」の場合、"getThree"の処理を行う Response["getValue"](); return; } else if (uri === "/post_data") { // URLが「IPアドレス/:1234/post_data」の場合、"postData"の処理を行う Response["postData"](); }; }); // 指定されたポート(1234)でコネクションの受け入れを開始する server.listen(1234); console.log('Server running ');

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ノーチェックなので予想でしか無いですがソースコメントで記載しておきます

JavaScript

1 collection.find({}).sort({ time: -1 }).toArray(function (err, docs) { 2 console.log("はいった"); 3 for (let doc of docs) { 4 result = doc; 5 break; 6 } 7 //value = docs; 8 // ここでresolveするべきでは 9 }); 10 11 process.on('unhandledRejection', console.dir) 12 resolve(result); // <-ここでresolveしてるけど、collection.findが非同期でしょうからresultは空では?

投稿2019/09/06 02:39

rururu3

総合スコア5545

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aiai8976

2019/09/06 02:47

ありがとうございます!いけました! collection.findも非同期なので空のままresolveを返してしまっていたということですね。 勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問