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

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

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

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

Q&A

解決済

2回答

1547閲覧

promiseにthenをメソッドチェーンした場合の挙動

domidomi

総合スコア34

JavaScript

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

0グッド

0クリップ

投稿2019/06/11 02:29

promiseについて勉強しており、thenメソッドチェーンによって1秒ごとにコンソールに何かが表示される処理を作ってみようと思いました。

そこでpromiseオブジェクトを返す以下の関数を書き【その1】で実行してみると

javascript

1var delay = time => { 2 return new Promise((r=>{ 3 setTimeout(()=>{ 4 r(); 5 },time) 6 })) 7}

javascript

1#############その1############ 2 3delay(1000) 4 .then(()=>{ 5 console.log("bbbb"); 6 delay(1000) 7 }) 8 .then(()=>{ 9 console.log("cccc"); 10 })

1000msたった後、bbbbとccccが同時に出力されてしまいました。
以下の【その2】、【その3】では1秒おきにうまく出力することができました。

javascript

1#############その2############ 2 3delay(1000) 4 .then(()=>{ 5 console.log("bbbb"); 6 return new Promise((r=>{ 7 setTimeout(()=>{ 8 r(); 9 },1000) 10 })) 11 }) 12 .then(()=>{ 13 console.log("cccc"); 14 })

javascript

1#############その3############ 2 3delay(1000) 4 .then(()=>{ 5 console.log("bbbb"); 6 return delay(1000) 7 }) 8 .then(()=>{ 9 console.log("cccc"); 10 })

#疑問
なぜpromiseオブジェクトをreturnするdelay関数が書いてあるだけ(その1)では、うまくいかなかったのでしょうか?
thenにおけるreturnの解釈のされ方がいまいちわかりません。

#思ったこと

delayは呼び出し元に対してpromiseオブジェクト返却する関数です。その2もpromiseオブジェクトをそのまま返却していると思います(名前がついているかついていないかの違い?)

なるほど、thenの中でpromiseオブジェクトを生成しなくちゃいけないのかと思ったのですが【その3】というpromiseオブジェクトを返却する関数を返却してみたらうまく作動する・・・なぜだ・・

書いていてまた混乱してきてしまいました・・・駄文すみません

どなたかご教示いただけると幸いです。

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

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

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

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

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

guest

回答2

0

ベストアンサー

なぜpromiseオブジェクトをreturnするdelay関数が書いてあるだけ(その1)では、うまくいかなかったのでしょうか?

その1では、promisereturnしていませんthenの中のdelayは作られはしますが、ただ放置されています。もちろん、処理の流れに影響を与えることもありません。

投稿2019/06/11 02:46

maisumakun

総合スコア145184

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

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

domidomi

2019/06/11 03:07

回答ありがとうございます。つまり その1のthenの中のdelay(1000)は、あくまでdelay(1000)にたいしてpromiseが返却されているだけであり、本当に返却したいthen()に対してpromiseが返却されているわけではない。そのためthenの勝手にpromiseを返すという機能が発動し、関数thenの中身は一通り終わったのでresolve状態promiseが返され次のthenが即発動した。 その2,3ではreturnを書くことによりthen()に対してpromiseが返却されるため、勝手にresolve状態promiseが返却されることは無く、delay(1000)内でpromiseがresolve状態になるのを待っていた。 thenの中にpromiseを返却する処理があるかないかは、構文解釈される際にjsエンジンがいい感じに理解してくれている。 という考えてあっているでしょうか?
maisumakun

2019/06/11 03:15

> thenの中にpromiseを返却する処理があるかないかは、構文解釈される際にjsエンジンがいい感じに理解してくれている。 いえ、そういうことではありません。.then自体が「コールバックがPromiseを返せばそのPromiseを返す、そうでなければ結果の値をresolveしたPromiseに詰めて返す」という関数になっているだけで、構文解析の特別な処理は全くありません。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/then#%E8%BF%94%E5%80%A4 なお、returnのない関数も、undefinedを返す関数とみなされます。
domidomi

2019/06/11 03:27

とても納得しました。ありがとうございました!
guest

0

async/awaitで処理してください

javascript

1const delay = time => { 2 return new Promise((r=>{ 3 setTimeout(()=>{ 4 r(); 5 },time) 6 })) 7} 8delay(1000).then(async()=>{ 9 console.log("bbbb"); 10 await delay(1000); 11}).then(()=>{ 12 console.log("cccc"); 13});

投稿2019/06/11 02:36

yambejp

総合スコア114839

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

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

domidomi

2019/06/11 03:08

async/awaitについて理解が深まりました ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問