回答編集履歴

1

コメントに対応

2018/10/23 14:53

投稿

miyabi-sun
miyabi-sun

スコア21158

test CHANGED
@@ -81,3 +81,131 @@
81
81
  少し難しい概念なので、私の説明で理解出来なければ
82
82
 
83
83
  書籍や他のサイトを見ながらじっくり学習していくと良いかと思います。
84
+
85
+
86
+
87
+ ---
88
+
89
+
90
+
91
+ 『修正後コード』
92
+
93
+
94
+
95
+ > `res = JSON.parse(body);`
96
+
97
+
98
+
99
+ これはなんですか?
100
+
101
+ JSのスコープとコールバックは癖が強く、他言語使いだと面食らうかと思いますが、
102
+
103
+ Node.jsはこのスコープとコールバックが一生つきまとう言語なので正しい理解が出来ないと何も作れません。
104
+
105
+ サイ本等を読む等して頑張って学習していきましょう。
106
+
107
+
108
+
109
+ まずは、動いているお手本をさらっとおさらいしましょう。
110
+
111
+
112
+
113
+ ```JavaScript
114
+
115
+ res.on('end', (chunk) => {
116
+
117
+ // body の値を json としてパースしている
118
+
119
+ res = JSON.parse(body);
120
+
121
+ console.log(`現在のレートは${res.rate}円/XRP`);
122
+
123
+ })
124
+
125
+ ```
126
+
127
+
128
+
129
+ 貴方がやりたい事を言語化すると、`JSON.parse(body)`を関数の外に持ち出したい。
130
+
131
+ そしてExpressのRouterに突っ込んだ関数で再現したい。
132
+
133
+
134
+
135
+ 上の説明では、変数はスコープを上に辿って探すことしか出来ないと言いましたね。
136
+
137
+ なので変数スコープの上段の方で先に宣言してしまい、
138
+
139
+ 中の関数には「この変数スコープには無いから上に探しに行こう、見つけた!」とさせる事が重要です。
140
+
141
+
142
+
143
+ 流石にグローバル変数に宣言するのはやめたほうが良いので、
144
+
145
+ require先のスコープの最上段くらいが無難ですかね。
146
+
147
+ 状態を表す`state`みたいな名前で宣言しておきましょう。
148
+
149
+
150
+
151
+ ```JavaScript
152
+
153
+ const XRP = "https://coincheck.com/api/rate/xrp_jpy";
154
+
155
+ const state = {};
156
+
157
+
158
+
159
+ // 中略
160
+
161
+
162
+
163
+ res.on('end', (chunk) => {
164
+
165
+ state.rate = JSON.parse(body);
166
+
167
+ })
168
+
169
+
170
+
171
+ // 中略
172
+
173
+
174
+
175
+ router.get('/', (req, res, next) => {
176
+
177
+ res.render('top', {
178
+
179
+ title: 'TOP',
180
+
181
+ rate: `現在のレートは${state.rate}円/XRP`
182
+
183
+ });
184
+
185
+ });
186
+
187
+ ```
188
+
189
+
190
+
191
+ ---
192
+
193
+
194
+
195
+ おまけのおまけ
196
+
197
+
198
+
199
+ …で、貴方の次の質問は「rate`の数字が一生変化しないよ!」になることでしょう。
200
+
201
+ 5分、10分おきにhttpリクエストを飛ばしてstate.rateを更新する作りにした方が良いでしょう。
202
+
203
+ Node.jsでも[setTimeout](https://developer.mozilla.org/ja/docs/Web/API/WindowTimers/setTimeout)や[setInterval](https://developer.mozilla.org/ja/docs/Web/API/Window/setInterval)が利用出来るので、https.getをまるごと関数で包んでこれらの関数で定期実行する仕組みにすれば実現出来ると思います。
204
+
205
+
206
+
207
+ まぁ、コインチェックAPIはWebSocketで常に最新の情報が取得出来るんで、
208
+
209
+ もし私が実装するならそちらを利用して常に最新のレートが取得出来るように見張ります。
210
+
211
+ これはこれで実装までが長い道のりだと思うので、着実に勉強していってください。