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

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

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

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

Q&A

解決済

2回答

1635閲覧

Promiseが返ってこなくなる

kuniatsu

総合スコア141

JavaScript

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

0グッド

1クリップ

投稿2019/02/07 03:19

再起呼び出しした後処理が返ってこなくなります。

html

1<html> 2<script> 3 (()=>{ 4 let i = 0; 5 let start = async ()=>{ 6 console.log("start()"); 7 await timeCount(); 8 console.log("END"); 9 } 10 11 let timeCount = async ()=>{ 12 console.log("timeCount()"); 13 await everySecond(()=>{ 14 let loopFlg = true; 15 i++; 16 if(i > 2){ 17 loopFlg = false; 18 } 19 return loopFlg; 20 }); 21 }; 22 23 let everySecond = (callback)=>{ 24 console.log("everySecond()"); 25 return new Promise((res)=>{ 26 setTimeout(async ()=>{ 27 let loopFlg = callback(); 28 if(loopFlg==true){ 29 let r = await everySecond(callback); 30 console.log("end"); 31 return r; 32 } 33 },1000); 34 }); 35 } 36 37 start(); 38 })(); 39</script> 40</html>

log

1start() 2timeCount() 3everySecond() 4everySecond() 5everySecond()

再起している処理が戻ってきて
console.log("end");
が3連続実行されて、
console.log("END");
を出して終わると考えて書いたのですが、
new Promiseが返ってきませんでした。

どのように書けば良いのでしょうか?
よろしくお願いします。

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

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

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

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

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

guest

回答2

0

もう少しPromiseへの理解が進めば自然と解決すると思うので
頑張って翻訳したりしながら勉強してください。

ポイントとしては下記2つを抑えましょう

  • async/awaitはPromiseの糖衣構文である
  • async/awaitでは、従来のコールバック関数での非同期処理を置き換えられない

これはちょっとした例が必要かな。

JavaScript

1const getUser = cb => { 2 // 本来はAjaxなりHTTPリクエストなりを発射してるはずだけど手抜きでsetTimeoutを利用 3 setTimeout(() => { 4 const err = null; 5 const user = {name: "taro", age: 18}; 6 cb(err, user); 7 }, 0); 8} 9 10const getUserPromise = async () => getUser((err, user) => user) 11 12const main = async () => { 13 const user = await getUserPromise; 14 console.log(user); 15}

質問文を簡略化するとこんな感じになりますがこれは動きません。
なぜならgetUserPromiseの中身は下記のように解釈されるからです。

JavaScript

1// 実際に解釈されるコード 2const getUserPromise = () => new Promise((resolve, reject) => { 3 resolve(getUser((err, user) => user)); 4}); 5 6// 理想(こうなってくれれば正常に動作する) 7const getUserPromise = () => new Promise((resolve, reject) => { 8 getUser((err, user) => resolve(user)); 9});

もしresolveの関数実行の箇所で動く・動かないに関して理解が不足しているならばPromiseを勉強してください。
Promise - MDN - Mozilla

asyncはreturnをresolve、throwをrejectという関数実行に置き換えますので、
このような理想と現実の差異が出ます。
実際に解釈されるコードは「おまえそこでresolveで包んでも全く意味ねーよ」という感じで全く使い物になりません。

なので従来の非同期処理のコールバック関数をPromise系にラッピングする場合、
async/await構文で横着が出来ず従来のPromise構文で書いてやる必要があります。

下記の記事のように、Node.jsの非同期関数の慣習に従って実装された綺麗な非同期処理の関数ならば、
promisifyが使えるのでこれでラッピングして使う事が可能です。
util.promisify が追加された

投稿2019/02/07 04:24

miyabi-sun

総合スコア21158

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

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

0

ベストアンサー

everySecondで作るPromiseで、一切resが呼ばれていないため、このPromiseは永遠にresolveしません。

setTimeoutは返り値を無視しますので、中身がasync関数となっていてPromiseを返そうが、それは無関係です。

投稿2019/02/07 03:33

編集2019/02/07 03:34
maisumakun

総合スコア145184

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問