awaitとasyncの使い方についての質問です。
「awaitを使うと値がreturnされるまで処理が一時停止される」という理解で以下のコードを記述しましたが、正しく動きません。
js
1dothis(); 2 3async function dothis(){ 4 console.log('1') 5 console.log(await say2()) 6 console.log('3') 7} 8 9async function say2() { 10 setTimeout(() => { 11 return 2; 12 }, 1000) 13}
こちらを実行すると
js
11 2undefined 33 // この後1秒待ってからプログラムが終了する。
となってしまいます。
実現したい結果は以下です。
js
11 // ここで1秒止まって 22 33
どうすればよいのでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
そやねえ。見たとこ3点ありよる。
(1) say2()
を
javascript
1 function say2() { 2 return new Promise(resolve => { 3 setTimeout(() => { 4 resolve(2) 5 }, 1000) 6 }) 7 }
に修正
(2) dothis
の呼び出しにも await
を付ける。
javascript
1await dothis();
(3) そして最後に、これらを含む関数も async
にしとく。
➡ サンプル
投稿2021/09/19 07:16
編集2021/09/22 17:11退会済みユーザー
総合スコア0
0
ベストアンサー
1 . setTimeout内のreturnについて
js
1async function say2() { 2 setTimeout(() => { 3 return 2; 4 }, 1000) 5}
この中の、() => {return 2;}
は、say2とは別の関数であるため、returnで返る場所はawait say2()
ではありません。(setTimeoutが戻り値を操作しないので、実質どこにも返していないです)
2 . say2の終了時点について
say2の中でsetTimeoutを使った第一引数に書かれている関数は、async/awaitを使っていない呼び出しと同じです。つまり内部の関数の終了を待ちません。
そのため、say2でawaitに該当する箇所がなく、即時に関数が終了します。
(何が言いたいかというと、仮にreturn 2が正しく返せても、出力は1,3,2になります)
1,2から、戻り値を正しい順に、適切に返す記述が必要になります。
今回はPromiseを使いますが、説明が長くなるので詳しくは一度調べてみてください。
js
1async function say2() { 2 const ret = await new Promise((resolve) =>{ 3 setTimeout(() => { 4 resolve(2); 5 }, 1000)} 6 ); 7 return ret; // 変数に一度置いていますが、直でreturnしてもいいです 8}
本来取得したい2
をresolveで受け、またawaitで待機してから返すことで、期待した動きになっているのではないでしょうか。
投稿2021/09/19 07:25
総合スコア1139
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/09/19 07:48
2021/09/19 08:01
2021/09/19 08:06
退会済みユーザー
2021/09/27 14:27
2021/09/27 14:36
0
returnされてるのがsetTimeoutだからだと思います。
例えば下記のようにすると
js
1async function say2() { 2 console.log("call"); 3 setTimeout(() => { 4 return 2; 5 }, 1000) 6} 7/** 81 9call 10undefined 113 12**/
ちゃんと通ってるのが分かります。
returnはあくまでsetTimeoutをreturnしただけで、say2()がreturnされたわけではないのでundefined(返却値がないという意味)となっています。
say2()の中でsetTimeoutを呼び出すのではなく、「1秒後に2をreturnするsay2()を呼び出す」ようにすれば良いのではないでしょうか?
投稿2021/09/19 07:11
編集2021/09/19 07:12総合スコア80875
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。