回答編集履歴

1

おまけ追加

2018/03/21 07:35

投稿

miyabi-sun
miyabi-sun

スコア21203

test CHANGED
@@ -31,3 +31,265 @@
31
31
  コールバックがない場合mysql2はPromiseを返す挙動になっているはずですが、
32
32
 
33
33
  コールバック関数を指定した場合の挙動は私は把握してませんね…もし気になるならソースコードを実際に読んでみてください。
34
+
35
+
36
+
37
+ ---
38
+
39
+
40
+
41
+ 【おまけ】 完成版コードへの軽いレビュー
42
+
43
+
44
+
45
+ お疲れ様でした、ぐっと見やすい良いコードになりましたね。
46
+
47
+ 折角なのでこの完成版コードを軽く見ていきます。
48
+
49
+
50
+
51
+ - poolは直接queryメソッド叩いて使える
52
+
53
+ - Promise.allと併用して並列処理っぽく
54
+
55
+ - Promiseをリスト操作で生成する
56
+
57
+ - asyncで作った関数はresolve, rejectを意識する
58
+
59
+
60
+
61
+ > poolは直接queryメソッド叩いて使える
62
+
63
+
64
+
65
+ もう見たまんまです。
66
+
67
+ connを取り出しても良いですが、このまま使った方が楽ちんでしょう。
68
+
69
+
70
+
71
+ ```JavaScript
72
+
73
+ const test = async () => {
74
+
75
+ const [rows_1, fields_1] = await pool.query('SELECT * FROM hoge_1');
76
+
77
+ console.log(rows_1);
78
+
79
+
80
+
81
+ const [rows_2, fields_2] = await pool.query('SELECT * FROM hoge_2');
82
+
83
+ console.log(rows_2);
84
+
85
+
86
+
87
+ const [rows_3, fields_3] = await pool.query('SELECT * FROM hoge_3');
88
+
89
+ console.log(rows_3);
90
+
91
+
92
+
93
+ await pool.end();
94
+
95
+ }
96
+
97
+ ```
98
+
99
+
100
+
101
+ > Promise.allと併用して並列処理っぽく
102
+
103
+
104
+
105
+ まずはこのコードをデベロッパーツールに突っ込んで結果を見て下さい。
106
+
107
+ 戻り値がPromiseであることが確認出来ます。
108
+
109
+ (Numberの配列なんで即resolvedしてますが)
110
+
111
+
112
+
113
+ ```JavaScript
114
+
115
+ Promise.all([123]);
116
+
117
+ // Promise {<resolved>: Array(1)}
118
+
119
+ ```
120
+
121
+
122
+
123
+ つまり、このように書けば並列処理になります。
124
+
125
+ これならばpoolでコネクションを複数本引っ張った意味も出来るでしょう。
126
+
127
+ (ちょっとこれを走らせて速度を確認してみてください。)
128
+
129
+
130
+
131
+ ```JavaScript
132
+
133
+ const test = async () => {
134
+
135
+ const results = await Promise.all([
136
+
137
+ pool.query('SELECT * FROM hoge_1'),
138
+
139
+ pool.query('SELECT * FROM hoge_2'),
140
+
141
+ pool.query('SELECT * FROM hoge_3')
142
+
143
+ ]);
144
+
145
+ console.log(results);
146
+
147
+
148
+
149
+ await pool.end();
150
+
151
+ }
152
+
153
+ ```
154
+
155
+
156
+
157
+ > Promiseをリスト操作で生成する
158
+
159
+
160
+
161
+ pool.query何回も実行してますが、これはダサいです。
162
+
163
+ sqlの配列から動的に作るようにしましょう。
164
+
165
+
166
+
167
+ 前項ではコードがキモい感じでしたが、
168
+
169
+ 多少そのキモさが和らいでるのが確認できます。
170
+
171
+
172
+
173
+ ```JavaScript
174
+
175
+ const test = async () => {
176
+
177
+ const sqls = [
178
+
179
+ 'SELECT * FROM hoge_1',
180
+
181
+ 'SELECT * FROM hoge_2',
182
+
183
+ 'SELECT * FROM hoge_3'
184
+
185
+ ];
186
+
187
+ const promises = sqls.map(sql => pool.query(sql));
188
+
189
+ const results = await Promise.all(promises);
190
+
191
+ console.log(results);
192
+
193
+
194
+
195
+ await pool.end();
196
+
197
+ }
198
+
199
+ ```
200
+
201
+
202
+
203
+ > asyncで作った関数はresolve, rejectを意識する
204
+
205
+
206
+
207
+ これは実践とはかけ離れた条件下なので、既にやっていることかもしれませんが、
208
+
209
+ asyncはawaitの逆、つまり絶対にpromiseを返す関数として振る舞います。
210
+
211
+
212
+
213
+ - returnで値を返せばresolve(value)と等価
214
+
215
+ - throwで例外を投げればreject(err)と等価
216
+
217
+
218
+
219
+ 特にtestの外でコネクションを張っておきながら、testの中で閉じるのもおかしな話です。
220
+
221
+ 実践を見据えてその辺を解消していきます。
222
+
223
+
224
+
225
+ ```JavaScript
226
+
227
+ const mysql = require('mysql2/promise');
228
+
229
+
230
+
231
+ const pool = mysql.createPool({
232
+
233
+ host: 'localhost',
234
+
235
+ user: 'foo',
236
+
237
+ password: '',
238
+
239
+ database: 'test'
240
+
241
+ });
242
+
243
+
244
+
245
+ const test = pool => {
246
+
247
+ const sqls = [
248
+
249
+ 'SELECT * FROM hoge_1',
250
+
251
+ 'SELECT * FROM hoge_2',
252
+
253
+ 'SELECT * FROM hoge_3'
254
+
255
+ ];
256
+
257
+ return Promises.all(sqls.map(sql => pool.query(sql)));
258
+
259
+ }
260
+
261
+
262
+
263
+ test(pool)
264
+
265
+ .then(results => {
266
+
267
+ console.log(results);
268
+
269
+ pool.end();
270
+
271
+ })
272
+
273
+ .catch(err => {
274
+
275
+ console.error(err);
276
+
277
+ pool.end();
278
+
279
+ });
280
+
281
+ ```
282
+
283
+
284
+
285
+ リファクタリング1号としてはこんな感じになりました。
286
+
287
+ ついでにtest関数がPromise.allを直接返すのでasync指定が剥げちゃいましたね…
288
+
289
+
290
+
291
+ まぁ、関数ってのは値を入れたら結果を返すものなので、
292
+
293
+ このようにsql結果を受け取り、`.then`や`.catch`を使って値を調査、poolを閉じた方が設計としては綺麗だと思います。
294
+
295
+ 実践は色々また状況が違うので最適なコードも変わってくると思います、頑張ってください!