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

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

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

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

Q&A

1回答

1906閲覧

Promiseが期待通りの動作をしない

rera

総合スコア109

Node.js

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

0グッド

1クリップ

投稿2017/05/27 06:24

Javascript

1module.exports.getHoge = (userId, date) => new Promise((resolve, reject) => { 2 ...省略 3 4 Promise.all([hoge1(userId, date), hoge2(userId, date)]) 5 ... 省略 6 7 .then(() => { 8 console.log('3 then'); 9 10 connection.connect(); 11 connection.query(`SELECT * FROM hoge_photos WHERE app_id = ${appId};`, (err, rows, fields) => { 12 if(err){ 13 console.log('mysql2 err'); 14 console.log(err); 15 throw err; 16 } else { 17 console.log('ここが期待通りじゃない'); 18 console.log(rows); 19 _.forEach(rows, (v, k) => { 20 arrPhoto.push(`${s3BucketURL}/${userId}/${v.app_id}/${rows[k].photo_hoge}`); 21 isPhotoData[arrKey]['photo'] = arrPhoto; 22 }); 23 } 24 }); 25 26 }) 27 .then(() => { 28 console.log('4 then'); 29 resolve(_.union(isPhotoData, isNoPhotoData)); 30 }); 31});

上記のようなコードがあるのですが
これを実行すると

1 then 2 then 3 then 4 then ここが期待通りじゃない [ TextRow { hoge: hoge } ]

3 thenの後にここが期待通りじゃない処理が来てほしいのですが
connection.queryの部分が非同期処理のために4 thenの後に結果がきているのが原因だと思っています。

このような場合、私が期待している3 thenの後に
connection.queryの結果がくるにはどうしたら良いのでしょうか?

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

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

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

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

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

guest

回答1

0

Promiseのメソッドチェーンのthenでさらに非同期処理をしたい場合、素朴な解決法はthenでPromiseを返すようにすることだと思います。ちなみにconnectで接続完了を待たずにqueryしているのはイケナイことのように見えますが大丈夫なんでしょうか・・・

javascript

1... 2promise.then(() => { 3 new Promise((resolve, reject) => { 4 connection.connect((err) => { 5 if (err) 6 reject(); 7 else 8 resolve(); 9 }) 10 }) 11}).then(() => { 12 new Promise((resolve, reject) => { 13 connection.query("...", (err, rows, fields) => { 14 if (err) 15 reject() 16 else { 17 //rowsに対する処理 18 resolve(); 19 } 20 }) 21 }) 22}).then(...)

こうした書き方をするのは非常に苦痛なのでPromiseを返すような非同期処理関数をconnectやqueryに対して用意しておき、以下のように書くと多少苦痛が減るかも知れません。

javascript

1function asyncConnect(conn) { 2 return new Promise((resolve, reject) => { 3 conn.connect((err) => { 4 if (err) reject() else resolve() 5 }) 6 }) 7}) 8 9function asyncQuery(conn, sql, cb) { 10 return new Promise((resolve, reject) => { 11 conn.query(sql, (err, rows, fields) => { 12 if (err) 13 reject() 14 else { 15 cb(rows, fields) 16 resolve() 17 } 18 }) 19 }) 20} 21 22... 23 24promise 25.then(asyncConnect(connection)) 26.then(asyncQuery(connection, "select ...", (rows, fields) => { 27 ... 28}) 29.then(...) 30... 31

投稿2017/05/27 08:10

KSwordOfHaste

総合スコア18392

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問