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

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

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

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

Q&A

解決済

2回答

8798閲覧

javascriptのthenの結果を外部から利用する方法

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

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

1グッド

1クリップ

投稿2019/08/18 00:43

編集2019/08/18 07:39

前提・実現したいこと

javascript(node.js)のthenの結果を外部からの呼び出しで利用したい場合、どのように書けばいいのでしょうか。
somePromiseReturnMethodはサードパーティライブラリの関数で、作り変えることができないものになります。
色々検索しましたが、thenの処理結果を外部で活用しているようなコードがあまり出てこず、
そもそもの使い方や発想が間違っているなどありましたらご指摘ください。
この記事を読んでから出直せ、などでも構いません。
どうぞよろしくお願いいたします。

発生している問題・エラーメッセージ

thenのレスポンスを外部から活用したいがPromiseしか取れず、awaitしてもUnhandledPromiseRejectionWarningなどのエラーになって意図した通りにならない

該当のソースコード

module1.js

javascript

1module.exports.getSomething = (key) => { 2 let result = false; 3 somePromiseReturnMethod(key) 4 .then(response => { 5 // result = response.val; // ケース1 6 // console.log(response.val); // ケース11 意図した値になる 7 8 // return response.val; // ケース2 Promiseが返る 9 10 }); 11 // return result; // ケース1 Promiseが返る 12};

index.js

javascript

1const {getSomething} = require("module1"); 2// 必ずtrueになる.getSomethingのresultが欲しい 3 4if (!getSomething(key)) { 5 // do something... 6} 7 8// or 9// UnhandledPromiseRejectionWarning等が出てしまう 10await getSomething(key);

試したこと

awaitを使う

ケース1
letをスコープ外で定義しthen内部の結果を格納する

ケース2
then内部でreturnする(これはスコープが1つ抜けるだけなのでここで関数が終わるわけではないので意味がないと思いますが一応試したこととして・・・)

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

Node.js v10.16.0
VScode

qope👍を押しています

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

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

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

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

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

R.Mizukami

2019/08/18 04:48

外部というのはどのような状況なのでしょうか。 おそらく二つ目のソースのことを指しているのだと思いますが、これは一つ目のソースを普通に require 構文などで参照しているという理解であっていますか? それとも「外部」というのがブラウザ環境など Nodejs 外の環境を意味しているのでしょうか。 私の勘違いでなければ、「外部」を別のスレッドを生成して利用するという意味に受け取られて回答がついてしまっているように思います。
退会済みユーザー

退会済みユーザー

2019/08/18 07:40

ありがとうございます。ご指摘通り require 構文で参照という意味です。単純に関数でthenを含む文を括っている状況です。「外部」という書き方が誤解を招く内容で申し訳ございません。
guest

回答2

0

ベストアンサー

Promise オブジェクトの利用法について勘違いがあるようです。そのため、module.js の関数から意図したオブジェクトを返せていません。

結論としては、module.js で公開する関数は Promise オブジェクトを返し、

index.js では await を利用するか返り値の Promise オブジェクトの then メソッドを実行するなどして対応することになると思います。

↓module1.js

javascript

1module.exports.getSomething = (key) => { 2 let result = false; 3 return somePromiseReturnMethod(key) 4 .then(response => { 5 // response に対する処理 6 return response.val 7 }) 8}

↓index.js

javascript

1const {getSomething} = require("./module1"); 2 3getSomething(key) 4 .then(result => { 5 if(!result) { 6 // Do something ... 7 } 8 })

質問者様のコードが動作しない理由

ケース1:以下のコード

javascript

1module.exports.getSomething = (key) => { 2 let result = false; 3 somePromiseReturnMethod(key) 4 .then(response => { 5 result = response.val; // ケース1 6 }); 7 return result; // ケース1 Promiseが返る 8};

getSomething() の関数の返り値は ** 常に false ** のはずです。
なぜなら、関数の実行が終了した時点では .then(callback) メソッドのコールバック関数はまだ呼び出されておらず、結果 result 変数への再代入が行われる前に return result に到達してしまうからです。

したがって、 index.js の if 文は常に実行されます。

ケース2:

javascript

1module.exports.getSomething = (key) => { 2 let result = false; 3 somePromiseReturnMethod(key) 4 .then(response => { 5 return response.val; // ケース2 Promiseが返る 6 }) 7}

これはよく見たらわかると思いますが、 getSomething() 関数が何も返していません。

return response.val の行は、somePromiseReturnMethod(key).then(callback) に渡されたコールバック関数が結果を返すコードであり、getSomething() 関数から返るコード ではありません

つまり、
index.js の getSomething(key) の返り値は常に undefined になり、!undefinedtrue になるためやはり if 文は常に実行されます。

投稿2019/08/18 08:03

R.Mizukami

総合スコア1086

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

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

退会済みユーザー

退会済みユーザー

2019/08/19 14:47

R.Mizukami様、非常に詳しくありがとうございました。 index.js側からawaitやThenでpromiseの終了を待つというのを試してみましたが、なぜか処理がスルーされてしまい、結局promiseの処理の結果を取ることがThenの中でしかできない状況から脱出できませんでした。 せっかくお教えいただいたのに本来の方法でうまく解決できず申し訳ありません。会社側のサードパーティのAPIを今回の関数で叩いている関係で全文を乗せることが難しく、すっきりとした解決をかけずに本当に失礼します。 結局、axiosでAPIを叩くという全く別の方法で逃れることになりました。 次回、Promise周りで詰まった時に活用させていただきたく思います。
guest

0

sessionStorageを利用してください。
https://developer.mozilla.org/ja/docs/Web/API/Window/sessionStorage

投稿2019/08/18 00:47

yasutomi

総合スコア2937

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

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

退会済みユーザー

退会済みユーザー

2019/08/18 07:42

ありがとうございます。すみません、当方の説明不足でわかりにくい質問だった可能性が高いです。 しかしこの関数の存在はまだ知らなかったため、解決に使えるかどうか検証したいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問