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

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

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

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

Q&A

解決済

3回答

695閲覧

JavaScriptでasync await内で行った結果をreturnしたい

H-T

総合スコア4

JavaScript

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

0グッド

0クリップ

投稿2021/07/13 18:07

編集2021/07/13 18:13

前提・実現したいこと

JavaScriptでasync await内で行ったなんらかの処理(値の取得や判定等)を行った後にその結果をreturn値でtrue/falseまたは0や1などの情報を呼び出しもとのに返却したいのですがそういったことは可能でしょうか?
不可能な場合、何か代替案はあるでしょうか?

下記のソースで行いたいこと
(1)async await内で足し算を行う
(2)(1)の計算結果が10を超えるかどうかの判定を行う
(3)(2)の判定結果を呼び出し元に返却し、その結果により処理を分岐する。

###理想の結果

12 true (valueJudgmentのthen内のコンソールログ) true (test()のcallback関数呼び出し後のコンソールログ) true (onButtonのコンソールログ) Success

###実際の結果

Promise {<pending>} 12 true undefined Failed

該当のソースコード

index.html

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Asyncテスト</title> <script src="js/index.js"></script> </head> <body> <input type="button" value="ボタン" onclick="onButton()"> </body> </html>

index.js

function onButton(){ test().then(res=>{ console.log(res); // 結果がtrueの場合成功/falseの場合は失敗と表示したい if(res){ console.log("Success"); }else{ console.log("Failed"); } }); } function test(){ // 計算データ let num1 = 5; let num2 = 7; async function callBack(){ let value = 0; await addCalculation(num1,num2).then(res=>{ //(2)計算結果(12)を表示 console.log(res); value = res; }) await valueJudgment(value).then(res=>{ //(3)数値判定結果(true)を表示 console.log(res); // true/falseを返したい return res; }) } // true/falseが帰ってきて欲しい let result = callBack(); // (1)Promise {<pending>}が表示される console.log(result); return result; } async function addCalculation(num1,num2){ // 計算 return num1 + num2; } async function valueJudgment(value){ // 計算結果が10以上か判定 if(10 < value){ return true; }else{ return false; } }

困っていること

元々は同期処理がうまくいってなかったのでasync awaitを利用しようとしているのですがasync awaitだとreturn値がPromiseのオブジェクトが返ってきてしまう・・・(true/falseを返したい)

###補足
上記の簡単な計算を例に挙げていますが実際は下記のことを行いたいです。
(1)画面初期表示にセッション情報を取得、判定を行うメソッドを呼び出す。
(2)セッション情報の判定結果(セッション情報があるかないか)を呼び出し元に返す。
(3)判定結果から画面の初期表示処理を行うかエラーページへ遷移するか分岐する。

※ちなみに、初期表示時にはDBのデータを表に表示する検索処理が行われます。
サンプルコードはhtmとjsを扱っていますが、実際はvueを使用しています。

別のやり口として、初期表示処理をcallback関数として引数で渡して、セッションの判定後のにその関数を実行するなども試してはいますがうまくいかず・・・
(下記のonInit関数を引数のcallback関数として渡しなどを試しているのですがうまくいかず・・・)

methods: { onInit : async function(){ await ・・・ } }

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

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

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

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

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

guest

回答3

0

ベストアンサー

サンプルコードのどの部分が実際にはどう変わるのか、というのがイマイチ分かりずらかったんで想像になりますが、おおよそ以下のような形になると思います。

恐らく、

  1. 画面読み込み時にonButtonに相当するセッションを確認する関数(※関数1)が発火
  2. 関数1の中でtestに相当するセッションの結果を返す関数(※関数2)が発火
  3. さらに関数2の中でcallbackに相当するセッションのget処理を行う非同期の関数(※関数3)が発火
  4. そして関数2関数3getの非同期処理を待って、関数3のレスポンスから判定した結果をreturn
  5. その返された値によって関数1内の処理を行う

という感じだと思います。

↑の通りだとするとベースは以下のような感じで、async関数内で適宜awaitを使ってレスポンスを受け取ればよいと思います。
Vueだとaxiosあたりを使ってるかと思うんですが、async関数内でconst response = await axios.get('/*****')のような形式で非同期処理を待ってレスポンスが取得できます。
fetchなども同様でPromiseベースのものでは基本的にこういった書き方ができます。(もちろんthenでメソッドチェーンする事も出来ますが、awaitを使うとあらかじめ変数を用意してthen内で受け取った値を代入...のような事をしなくて済みます)

また質問者さんのコードを拝見する限り、Promiseとは何か、async/awaitとは何か、というのをまだあまり理解されてないようだったので、一度その3つについて詳しく調べてみるとよいかと思います。
JavaScript Promiseの本
※他にもQiitaやZennに分かりやすい記事が沢山あります。

以上、ご参考になれば幸いです。

動作デモ

JavaScript

1const onButton = async () => { 2 const res = await test() 3 console.log(res) 4 const message = res ? 'Success' : 'Faild' 5 console.log(message) 6} 7 8const test = async () => { 9 const num1 = 5 10 const num2 = 7 11 12 const callBack = async () => { 13 const res = addCalculation(num1, num2) 14 console.log(res) 15 const res2 = valueJudgment(res) 16 console.log(res2) 17 return res2 18 } 19 20 const result = await callBack() 21 console.log(result) 22 23 return result; 24} 25 26const addCalculation = (num1, num2) => num1 + num2 27const valueJudgment = value => 10 < value

投稿2021/07/13 19:22

編集2021/07/13 19:26
taku-hu

総合スコア176

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

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

H-T

2021/07/14 12:23

迅速なご回答ありがとうございます。 処理自体は上手く行きました。 ご指摘していただいた通りPromiseやasync/awaitについての理解しておりませんでした。というよりはJavascript自体しっかり学べていなかったので関数の使い方もなんとなくで扱ってしまっているんですよね・・・今回のasync/awaitも現場で使用されているものをなんとなく使用していて、同期非同期をコントロールできることは分かったのですがそれがthenで処理するものだと思っていました。 なので教えていただいたサイトを参考にもう少ししっかりと学んでいきたいと思います。
guest

0

訂正しました

return 文がないのが直接的な原因だと思います。

js

1return await valueJudgment(value).then(res=>{

訂正前

test関数を非同期にすればいいのではないかと思いました。

js

1async function test(){ 2 // 計算データ 3 let num1 = 5; 4 let num2 = 7; 5 async function callBack(){ 6 let value = 0; 7 value = await addCalculation(num1,num2); 8 return await valueJudgment(value); 9 } 10 return await callBack(); 11}

投稿2021/07/14 00:41

編集2021/07/14 00:56
Lhankor_Mhy

総合スコア36117

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

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

H-T

2021/07/14 12:27

ご回答ありがとうございます。 awaitでreturnができるとは思っていませんでした。 今後の参考にさせていただきす。
guest

0

callBack()がasync(非同期)で呼び出されるので、

// (1)Promise {<pending>}が表示される console.log(result); return result;

が、callback()の処理結果を待たずに処理されるので、今の実装だと難しいですね。
やるのでしたら、callbackのthenに上の処理を入れる形になるのかなと思います。

そもそも、非同期というのはreturnを望まない(returnを期待するのは同期と変わらない)ので
async関数を同期的に書こうとすると、いわゆるコールバック地獄になると思います。

returnを期待するならば、理想は同期で行うことですが、
もともと用意されているライブラリ等の関数がasyncで定義されているなら
おとなしくthenで処理していくしかないと思います。

投稿2021/07/13 19:06

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

H-T

2021/07/14 12:24

ご回答ありがとうございます。 自分もコールバック地獄になりそうなので悩んでいました。
退会済みユーザー

退会済みユーザー

2021/07/14 16:42

非同期処理が生まれた歴史としては、当時のJavaScriptは動作が重く、 ブラウザのサービスで何とか利用者にストレスがないようにと生まれました。 (ご理解していると思いますが)上記の通りですので、非同期処理の動作としては ①A関数からB関数を呼び出す(非同期「async」) ②B関数の処理終了を待たずにA関数の処理を続行 →ブラウザではB関数の処理終了を待機しなくても良くなる。 という流れになる訳ですね。 ただし上記だと、B関数を同期的に使用したいシーンで不都合が生じます。 そこでさらにawaitというものを使用する事になった訳です。 各家庭にPC1台が普及し始めた時代に発展した言語なので その時の技術で、いかに利用者がストレスを感じないようにと 部屋を増築するかのように都度新しい技術が取り入れられて今に至ってます。 (ここがJavaScriptの便利なところであり、落とし穴でもあると思ってます。) Promiseの概念は、コード上でコールバック地獄になった際に 処理がネストされて(ソースが見づらくなって)しまう事を防げます。 と色々申してますが、解決したようで何よりです! 長々と失礼いたしました。
H-T

2021/07/14 16:54

いえいえ、大変参考になりました。 貴重なご意見ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問