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

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

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

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Node.js

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

Q&A

解決済

2回答

4454閲覧

MySQLのクエリ結果の戻り値が返ってこない

mu-ro

総合スコア20

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Node.js

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

0グッド

0クリップ

投稿2020/06/09 03:46

エラー内容

今現在、Node.jsにてexpressとMySQLを用いてプログラムを書いています。MySQLのテーブル情報(テーブル名:jobs)を呼び出すには毎回以下のプログラムを書かなくてはなりません。

app.js

1connection.query( 2 'select * from jobs', 3 (error, results) => { 4 5 } 6);

手間もかかり、繰り返し使用するとネストも深くなってしまうということで、以下のように関数を用いて呼び出してみることにしました。

app.js

1var getJobs = () => { 2 connection.query( 3 'select * from jobs', 4 (error, results) => { 5 return results; 6 } 7 ); 8} 9 10app.post("/check/:id", (req, res) => { 11 connection.query( 12 'select * from players where id = ?', 13 [req.params.id], 14 (error, results) => { 15 // ここで関数を呼び出し、返り値を出力 16 console.log(getJobs()); 17 18 res.render('check.ejs', {players: results[0]}); 19 } 20 ); 21}); 22

すると、以下のように未定義と表示されてしまいます。

console

1undefined

また、関数内でコンソール出力すると普通に表示されます。
なぜ返り値としてreturnするとundefinedになるのでしょうか。。。

実際のソースコード

app.js

1const express = require('express'); 2const mysql = require('mysql'); 3 4const app = express(); 5 6app.use(express.static('public')); 7app.use(express.urlencoded({ extended: false })); 8 9// 各種変数宣言 10var player = []; 11var jobList = []; 12var doubt = []; 13var kill = []; 14var divine = []; 15var jobsNum; 16 17class Player { 18 constructor(i, id, job) { 19 this.i = i; 20 this.id = id; 21 this.job = job; 22 } 23}; 24 25// データベース接続 26const connection = mysql.createConnection({ 27 "host": 'localhost', 28 "user": 'root', 29 "password": 'muro5866', 30 "database": 'werewolf' 31}); 32 33connection.connect((err) => { 34 if (err) { 35 console.log('error connecting: ' + err.stack); 36 return; 37 } 38}); 39 40// 関数 41var getJobs = () => { 42 connection.query( 43 'select * from jobs', 44 (error, results) => { 45 return results; 46 } 47 ); 48} 49 50var getPlayers = () => { 51 connection.query( 52 'select * from players', 53 (error, results) => { 54 return results; 55 } 56 ); 57} 58 59var voting = (name, radio, ) => { 60 if (name !== undefined) { 61 String(radio).split(','); 62 63 // console.log(radio); 64 65 var pId = radio[0]; 66 var jId = radio[2]; 67 68 // console.log(pId); 69 // console.log(jId); 70 71 connection.query( 72 'select * from jobs', 73 (error, results) => { 74 switch (results[jId-1].voting) { 75 case 'doubt': 76 doubt.push(pId); 77 break; 78 case 'divine': 79 divine.push(pId); 80 break; 81 case 'kill': 82 kill.push(pId); 83 break; 84 } 85 } 86 ); 87 } 88 return; 89} 90 91// レンダリング処理 92app.get('/', (req, res) => { 93 res.render("top.ejs"); 94}); 95 96app.get("/top", (req, res) => { 97 res.render("top.ejs"); 98}); 99 100app.get("/player", (req, res) => { 101 connection.query( 102 'select * from players', 103 (error, results) => { 104 res.render('player.ejs', {players: results}); 105 } 106 ); 107}); 108 109app.post("/register", (req, res) => { 110 connection.query( 111 'insert into players (name, status) values (?, \'alive\')', 112 [req.body.pname], 113 (error, results) => { 114 // res.render('player.ejs', {players: results}); 115 res.redirect('/player'); 116 } 117 ); 118}); 119 120app.post("/delete/:id", (req, res) => { 121 connection.query( 122 'delete from players where id = ?', 123 [req.params.id], 124 (error, results) => { 125 // res.redirect('player.ejs', {players: results}); 126 res.redirect('/player'); 127 } 128 ); 129}); 130 131app.post("/edit/:id", (req, res) => { 132 connection.query( 133 'update players set name = ? where id = ?', 134 [req.body.name, req.params.id], 135 (error, results) => { 136 // res.redirect('player.ejs', {players: results}); 137 res.redirect('/player'); 138 } 139 ); 140}); 141 142app.get("/explanation", (req, res) => { 143 res.render("explanation.ejs"); 144}); 145 146app.get("/back-top", (req, res) => { 147 res.render("top.ejs"); 148}); 149 150app.get("/job", (req, res) => { 151 connection.query( 152 'select * from jobs', 153 (error1, results1) => { 154 connection.query( 155 // 'select count(*) from players', 156 'select * from players', 157 (error2, results2) => { 158 for (var i = 0; i < results2.length; i++) { 159 player[i] = new Player(i, results2[i].id, undefined); 160 } 161 res.render('job.ejs', {jobs: results1, players:results2}); 162 } 163 ); 164 } 165 ); 166}); 167 168app.get("/settings", (req, res) => { 169 res.render("settings.ejs"); 170}); 171 172app.get("/back-job", (req, res) => { 173 res.render("job.ejs"); 174}); 175 176app.post("/start", (req, res) => { 177 connection.query( 178 'select * from players', 179 (error1, results1) => { 180 // 各役職の人数を配列に格納 181 jobsNum = req.body.jobs; 182 183 // 更新してしまった場合のためにPlayerの値入れ直し 184 for (var i = 0; i < results1.length; i++) { 185 player[i] = new Player(i, results1[i].id, undefined); 186 } 187 188 // 各プレイヤーの役職決定 189 // jobListに役職idを格納 190 for (var i = 0; i < Number(req.body.sum); i += j) { 191 for (var j = 0; j < jobsNum[i]; j++) { 192 jobList[i+j] = i + 1; 193 // console.log(jobList) 194 } 195 } 196 197 var len = jobList.length; 198 199 while (len) { 200 var j = Math.floor( Math.random() * len ); 201 var t = jobList[--len]; 202 jobList[len] = jobList[j]; 203 jobList[j] = t; 204 } 205 206 for (var i = 0; i < Number(req.body.sum); i++) { 207 player[i].job = jobList[i]; 208 connection.query( 209 'update players set jobid = ? where id = ?', 210 [jobList[i], player[i].id], 211 (error2, results2) => { 212 213 } 214 ); 215 } 216 res.render("start.ejs", {players: results1[0]}); 217 } 218 ); 219}); 220 221app.post("/check/:id", (req, res) => { 222 connection.query( 223 'select * from players where id = ?', 224 [req.params.id], 225 (error, results) => { 226 // morningでも同様にラジオ取得する 227 // ラジオによって投票処理 228 voting(req.body.name, req.body.radioGroup); 229 // var abc = []; 230 // abc = getJobs(); 231 console.log(getJobs()); 232 233 res.render('check.ejs', {players: results[0]}); 234 } 235 ); 236}); 237 238app.post("/night-action/:id", (req, res) => { 239 connection.query( 240 // このidの次のデータを合わせて取得 241 'select * from players where id >= ? order by id limit 2', 242 // 'select * from players where id = ?', 243 [req.params.id], 244 (error1, results1) => { 245 connection.query( 246 'select * from players', 247 (error2, results2) => { 248 connection.query( 249 'select * from jobs', 250 (error3, results3) => { 251 var job; 252 var pId; 253 254 // 更新してしまった場合のためにPlayerの値入れ直し 255 for (var i = 0; i < results2.length; i++) { 256 player[i] = new Player(i, results2[i].id, results2[i].jobid); 257 } 258 // console.log(player); 259 260 for (var i = 0; i < results2.length; i++) { 261 if (player[i].id === results1[0].id) { 262 // プレイヤーのjobId 263 var id = player[i].job; 264 job = results3[id-1]; 265 pId = player[i].id; 266 } 267 } 268 // console.log('job : ' + job); 269 270 connection.query( 271 // 'update players set job = ? where id = ?', 272 // [job.name, pId], 273 'update players set jobid = ? where id = ?', 274 [job.id, pId], 275 (error4, results4) => { 276 res.render('night-action.ejs', {mplayer: results1[0], nplayer: results1[1], players: results2, job: job}); 277 // res.render('check.ejs', {players: results1[0]}); 278 } 279 ); 280 } 281 ); 282 } 283 ) 284 // console.log(results); 285 // res.render('night-action.ejs', {players: results[0]}); 286 // res.render('check.ejs', {players: results}); 287 } 288 ); 289}); 290 291app.get("/morning", (req, res) => { 292 connection.query( 293 'select * from players', 294 (error, results) => { 295 res.render("morning.ejs"); 296 } 297 ); 298}); 299 300app.listen(3000); 301console.log("server listening..."); 302

試してみたこと

関数内のreturnの位置をconnection.queryの外に出してみましたが、だめでした。
どなたか、回答の方よろしくお願いします。

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

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

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

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

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

guest

回答2

0

なぜ返り値としてreturnするとundefinedになるのでしょうか。。。

query非同期実行されますので、getJobs関数からは、クエリの実行を待たずに戻ります。つまり、通常の返り値としてクエリの結果を受け渡しすることはできません。

投稿2020/06/09 04:05

maisumakun

総合スコア145183

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

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

mu-ro

2020/06/13 01:57

お礼が遅くなり申し訳ございません。非同期実行が原因だったのですね、ありがとうございます。
guest

0

ベストアンサー

原因は

JS

1var getJobs = () => { 2 connection.query( 3 'select * from jobs', 4 (error, results) => { 5 return results; 6 } 7 ); 8 // connection.queryは非同期関数なので 9 // すぐにここに来る 10 // 何も返してないのでundefinedになる 11}

です。

解決策として

投稿2020/06/09 04:00

rururu3

総合スコア5545

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

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

mu-ro

2020/06/13 01:59

お礼が遅くなり申し訳ございません。なるほど、connection.query処理は非同期で処理されずに何も行われてなかったのですね。解決策の内の3つ、難しいですがなんとか理解して実装してみようと思います。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問