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

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

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

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

2回答

172閲覧

node 同期処理について

yuunii

総合スコア10

Node.js

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2019/03/02 17:15

編集2019/03/02 17:17

前提・実現したいこと

promiseを使っているのですが、同期処理が行われない
undefinedのまま

該当のソースコード

javascript

1var xxx = async function () { 2return await getXXX() 3function getXXX() { 4return new Promise(function (resolve, reject) { 5 //リクエスト送信 6 request(options, function (error, response, body) { 7 if (error) { 8 reject(new Error(error.message)); 9 } 10 resolve(body) 11 }) 12 }) 13} 14 15console.log(xxx) // ←ここがundefinedになってしまう

試したこと

Promiseでは非同期になってしまうのかと思い、無理やりawaitを突っ込みました

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

node v10.0.0

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

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

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

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

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

guest

回答2

0

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();

投稿2019/03/06 07:53

miyabi-sun

総合スコア21158

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

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

0

単に関数xxxを実行していないからとかではなく?

javascript

1console.log(xxx()); // Promiseが返ってくるはず

投稿2019/03/06 06:59

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問