console.log(xxx) // ←ここがundefinedになってしまう
まだ実行しないのだからxxx
は関数になるはずです。
単純にインデントをサボっているのが原因じゃないですか?
質問文のコードはxxx内でconsole.log(xxx)
してませんか?
まぁ、それでも再帰関数と同じ挙動になるはずなので、そのスコープ内でxxxを確認してもやはり関数が表示されると思いますが……
きっとダイジェストとして切り貼りしている最中によく分からないことになったのだと思います。
promiseを使っているのですが、同期処理が行われない
Promiseを使っても非同期処理は非同期処理のままです。
Node.jsを含むJavaScriptはシングルスレッドです。
HTTP通信等のI/Oが絡む処理は何時結果が帰ってくるかわかりません。
なので、こういう処理は非同期で受けようという思想になっています。
同期のまま結果を待つとブラウザが止まりますからね。
Node.jsもHTTPサーバとしての意識が強いのですが、裏でHTTPリクエストを飛ばす等して固まったら、
後続のHTTPリクエストが全て詰まってしまいます。
なので「非同期で処理しといてねよろしく」と言いながら次々とリクエストを捌く必要があります。
非同期処理は同期処理には二度と戻れません。
PromiseはJS名物コールバック地獄へのカウンターとして考案されたもので、
.then(fn)
メソッドで繋げれば関数定義のネストが1回で済むじゃん!と言ってるだけのものです。
Promiseでは非同期になってしまうのかと思い、無理やりawaitを突っ込みました
async/await構文も同様で、非同期処理は非同期処理のままです。
これはPromiseを使った書き方の糖衣構文で、見てくれだけ同期処理っぽく記述出来るだけです。
つまり、async関数内ではあたかも同期処理のようなコードを記述できますが、
その実態は関数をまるっとPromiseで包み込んだものなので、外に出たら単なるPromiseインスタンスとして取り扱わなければなりません。
まず、質問文をES7相当に書き直したのがこちら
関数定義をconst+アロー関数にしています。
JavaScript
1const getXXX = () => new Promise((resolve, reject) =>
2 // リクエスト送信
3 request(options, (error, response, body) => {
4 if (error) return reject(error);
5 resolve(body);
6 })
7);
8const xxx = async () => await getXXX();
9
10console.log(xxx); // fn <- 単なる関数定義なので関数が表示される
11
12// Promiseらしくthenで関数を指定してやる事で結果のbodyを取り出す事が可能となる。
13xxx().then(console.log);
このxxx
のasync/awaitを解除してES6相当に書き直したのがこちら
JavaScript
1const xxx = () => {
2 let promise = Promise.resolve(null);
3 return promise.then(() => getXXX());
4}
元々処理自体がシンプルなので大した変更点はありませんが、
こんな感じになります。
私は全てを忘れて同期的に書きたいんだ!!
main関数を用意しましょう。
まぁC言語みたいなのにあやかっただけで、別に即時実行関数でもなんでも良いですが……
その中でやりたい事を全て書いてください。
JavaScript
1const getXXX = () => new Promise((resolve, reject) =>
2 // リクエスト送信
3 request(options, (error, response, body) => {
4 if (error) return reject(error);
5 resolve(body);
6 })
7);
8
9// メイン関数を定義
10const main = async () => {
11 // そもそもpromise返すだけだからxxx関数いらんかったわ、がはは
12 console.log(await xxx());
13}
14
15// そのまま実行
16main();
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。