🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

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

Q&A

解決済

1回答

972閲覧

promise、async、awaitの処理順

torimingo

総合スコア122

JavaScript

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

0グッド

0クリップ

投稿2021/02/06 14:53

promise、async、awaitについて処理の流れがよくわかりません。
以下にソースコードを示します。

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <script> function sleep(ms){ return new Promise( function(resolve){ setTimeout(resolve, ms); } ); } async function hidoki(){ console.log("start sleep"); await sleep(2000); console.log("end sleep"); return 1; } let hi = hidoki(); console.log("main1"); hi.then( function(v){ console.log(v); } ); console.log("main2"); </script> </body> </html>

上記のプログラムは以下の流れで実行されると
なんとなく思えるのですが、誤りはありますでしょうか?

 1. hidoki()が実行される。
1. 「start sleep」が表示される。
1. setTimeout(resolve, ms);が実行される。
1. 2秒待ちが始まる。
1. let hi = hidoki();が実行される。
1. 「main1」が表示される。
1. hi.then(略);が実行されコールバック関数?が登録される。
1. 「main2」が表示される。
1. 2秒待ちが終わる。
1. 「end sleep」が表示される。
1. hi.then(略);の中のconsole.log(v);が実行される。

特にわからないのが、JavaScriptはシングルスレッドなのに、「await sleep(2000);」で2秒待ち開始直後に「let hi = hidoki();」で「hidoki()」の戻り値が「hi」に格納される(?)というところです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

  1. let hi = hidoki();が実行される。
  2. 「start sleep」が表示される。
  3. sleepが実行される
  4. setTimeout(resolve, ms);が実行される。
  5. 2秒待ちが始まる。
  6. sleepがawaitなので並行してconsole.log("main1")が実行される
  7. 「main1」が表示される。
  8. sleepが終わらないので「main2」が表示される。
  9. 2秒待ちが終わる。
  10. 「end sleep」が表示される。
  11. 1が戻される
  12. hidokiのthenに処理が流れて1が表示される

投稿2021/02/06 15:30

yambejp

総合スコア116694

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

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

torimingo

2021/02/07 00:27

ご返答をありがとうございます。 「6. sleepがawaitなので並行してconsole.log("main1")が実行される」というところが少しわかっておりません。sleep関数を以下に変更して実行すると「ループ中」という表示が終わってからでないと「main1」が表示されません。並行に実行されるとのことでしたら、100000個の「ループ中」という表示の間に「main1」が紛れ込むように表示されてもいいのかなと思いました。 function sleep(ms) { return new Promise( function(resolve) { for(let i = 0; i < 100000; ++i){ document.write("ループ中<br>"); resolve(); } } ); }
yambejp

2021/02/07 02:01 編集

では具体的に const hidoki=async()=>{ console.log("start"); console.log("end"); return 1; } let hi = hidoki().then(data=>console.log(data)); console.log("main"); 出力: start→end→main
yambejp

2021/02/07 02:01 編集

const hidoki=async()=>{ await console.log("start"); console.log("end"); return 1; } let hi = hidoki().then(data=>console.log(data)); console.log("main"); 出力: start→main→end
yambejp

2021/02/07 02:08

これが const sleep=ms=>new Promise(resolve=>setTimeout(()=>{console.log('sleep');resolve()}, ms)); const hidoki=async()=>{ console.log("start"); sleep(1000); console.log("end"); return 1; } let hi = hidoki().then(data=>console.log(data)); console.log("main"); 出力: start→end→main→1→sleep
yambejp

2021/02/07 02:10

const sleep=ms=>new Promise(resolve=>setTimeout(()=>{console.log('sleep');resolve()}, ms)); const hidoki=async()=>{ console.log("start"); await sleep(1000); console.log("end"); return 1; } let hi = hidoki().then(data=>console.log(data)); console.log("main"); 出力: start→main→sleep→end→1
yambejp

2021/02/07 02:30 編集

シングルスレッドの例 const wait=1000000000;//適当な長さ const hidoki=async()=>{ console.log("start"); var i=0; while(i<wait*2){i++}; console.log("end"); return 1; } let hi = hidoki().then(data=>console.log(data)); var j=0; while(j<wait){j++}; console.log("main"); 出力: start→end→main→1
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問