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

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

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

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

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Express

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

Q&A

解決済

1回答

1814閲覧

node.jsにおいて、入れ子となるSQL実行の結果を待って結果を返却したい

yosuke.ki

総合スコア1

Node.js

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

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Express

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

0グッド

0クリップ

投稿2020/07/11 13:32

前提・実現したいこと

以下の構成を利用しています。
・node.js
・Express.js
・mysql

1段階目のSQLとして親データを取得(複数行取得される)
2段階目として取得した親データに対して、それぞれに紐づく子データを取得するSQLを実行し、データをJSONに加工してレスポンスに乗せて返却する。

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

子データを取得するSQL実行が非同期実行となってしまい、親データだけの状態で返却されてしまう。
すべてのSQLが実行されたうえで、データを格納し返却したい。

該当のソースコード

node

1app.get('/getData', function(req,res) { 2 3 let resultData; 4 5 var data = req.body; 6 7 // 親データ取得SQL 8 let parentDataSql = "select bin_to_uuid(parent_id) as id, name, sort_no from parent"; 9 // 子データ取得SQL 10 let childDataSql = "select bin_to_uuid(child_id) as id, title from child where parent_id = uuid_to_bin(?)"; 11 12 con.query(parentDataSql, function(err, result, fields){ 13 if(err) throw err; 14 15 if(result.length > 0) { 16 resultData = result; 17 18 // parentで取得した行数分、childの取得を行う。 19 result.map((item) => { 20 // childDataSqlを実行 21 // ここが非同期処理となる 22 con.query(taskByStatus, item['parent_id'], async function(err, result, fields){ 23 if(err) throw err; 24 25 if(result.length > 0) { 26 item['items'] = result; 27 } else { 28 item['items'] = []; 29 } 30 }); 31 32 }); 33 // 子データ取得と、その結果をセットしてから返却したいが、con.query が非同期のため先に返却される 34 res.send(resultData); 35 36 } else { 37 resultData = ""; 38 return resultData; 39 } 40 }); 41});

試したこと

con.queryの箇所を配列にPushして、 res.sendの箇所を Promise.ALL()を使用してみたものの、子データ取得の処理を待つことはできませんでした。
(Promiseの理解度は高いとは言えないため、記述が間違っている可能性はあります)

補足情報(FW/ツールのバージョンなど)

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

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

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

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

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

guest

回答1

0

自己解決

自己解決です。
con.queryの実行処理を new Promiseでくくり、結果を配列に格納することで実現できました。

node

1 result.map((item) => { 2 promise.push( new Promise ( (resolve, reject) => { 3 con.query(childDataSql, item['id'], function(err, result, fields){ 4 if(err) throw err; 5 6 if(result.length > 0) { 7 item['items'] = result; 8 } else { 9 item['items'] = []; 10 } 11 resolve(); 12 }) 13 }))}); 14 15 16 17 Promise.all(promise).then(() => { 18 res.send(resultData); 19 });

投稿2020/07/11 14:31

yosuke.ki

総合スコア1

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問