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

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

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

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

JavaScript

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

Q&A

2回答

8053閲覧

コールバック関数から値を返したい

退会済みユーザー

退会済みユーザー

総合スコア0

Node.js

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

JavaScript

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

0グッド

2クリップ

投稿2018/04/01 19:54

HTTPクライアントを実装したいと思っています。

javascript以外の言語は経験があり、直感的に

<レスポンス> = <httpリクエスト> // レスポンスを使っていろいろ処理 ...

の用な感じでしたいです。
しかし、requestモジュールは

javascript

1request.get(options,function(error,response,body){ 2 console.log(body); 3});

のようになっていて、

javascript

1request.get(options,function(error,response,body){ 2 return body 3});

のようにするわけにはいきません。

どのようにしてレスポンスを

javascript

1function Exec(){ 2 request.get(options,function(error,response,body){ 3 return body 4 }); 5} 6var body = Exec()

のように受け取れるでしょうか?
ご教授よろしくお願いします。

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

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

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

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

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

guest

回答2

0

JavaScriptの言語設計モデルは非同期で処理することを前提にしています。(Node.jsの一部の関数を除けば)外部へ問い合わせしてその返答への待ちが発生するような関数は非同期で行われるため、コールバックで処理することが基本であり、他の言語のような返答があるまで待ってから処理するといった同期的な処理ができません。

非同期処理はシングルスレッドにおいて速度面で有利になるという利点があるのですが、そのままではコールバックを多用するため、いわゆるコールバック地獄という深いコールバックだらけで訳がわからないコードになってしまうと言う問題がありました。そこで、ES2015から追加されたのがPromiseです。しかし、Promiseでも使いやすいとは言えなかったため、より同期処理のように書けるようにしたのが、ES2017から追加されたasync関数です。

ということで、任意の非同期なコールバック関数は、Promise化し、async関数内でawaitを付けることで、同期処理のように書くことが可能になります。

JavaScript

1const request = require('request'); 2 3const requestPromise = (options) => new Promise((resolve, reject) => { 4 request(options, (error,response,body) => { 5 if (error == null) { 6 resolve(body); 7 } else { 8 reject(error); 9 } 10 }); 11}); 12 13(async function() { 14 const options = 'https://teratail.com/' 15 body = await requestPromise(options); 16 console.log(body); 17})()

上記ではasync関数を即時関数にしていますが、任意のタイミングで実行する事は可能です。ただし、async関数自体は非同期に実行されると言うことに注意してください。

また、requestの場合は、初めから三種類のPromise化済みパッケージが用意されています。自分でPromise化せずにパッケージを使っても構いません。その中の一つであるrequest-promise-nativeを使った場合は次のようになります。(他のはPromiseの実装方法の違いですので、やり方は同じです)

const requestPromise = require('request-promise-native'); (async function() { const options = 'https://teratail.com/' body = await requestPromise(options); console.log(body); })()

投稿2018/04/01 22:31

編集2018/04/02 12:36
raccy

総合スコア21735

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

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

0

すでに良回答があるので考え方だけ

もし仮に同期処理でも流れ的にはこうしないと戻り値は得られないですね

javascript

1function Exec(){ 2 var ret; 3 request.get(options,function(error,response,body){ 4 ret=body 5 }); 6 return ret; 7} 8var body = Exec()

非同期ならさらに工夫が必要でしょう

投稿2018/04/02 02:48

yambejp

総合スコア114747

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問