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

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

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

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

Q&A

解決済

2回答

4775閲覧

jsでコールバックがうまく実装できない

keys

総合スコア215

JavaScript

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

0グッド

0クリップ

投稿2018/03/29 18:55

編集2018/03/29 18:56

コールバックの練習をしています。(まだpromiseなどの高度なことしていません)やりたいことは、関数Aを実行したら、関数の中でループ処理が行われ、そのループが終わったら、関数Bを実行するというものです。下記のようにコードを書いてみたのですが、ループが終わる前にコールバック関数が実行されてしまいます。ループは一回ループする毎にひと時休憩するようにしてます。どのようにすれば上記のような実装が実現できるでしょうか?

js

1var after_callback = function() { 2 console.log('log after loop'); 3}; 4 5// loop-timeが終わってから引数を実行する関数 6var befoer_callback = function(callback) { 7 8console.log("loop start") 9 10var counter = 0; 11var i = setInterval(function(){ 12 console.log("loop-time") 13 counter++; 14 if(counter === 10) { 15 clearInterval(i); 16 } 17}, 200); 18 19//コールバックを実行 20befoer_callback(); 21}; 22 23myTurn(after_callback); 24//loop start 25//log after loop 26//10(index):121 loop-time

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

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

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

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

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

akabee

2018/03/29 23:57

このコードの中で、関数Aと関数Bはどれにあたりますか?また、myTurn関数の内容はどんなものですか?
guest

回答2

0

ベストアンサー

コードが不完全で, 内容の成否を確認できませんので, シンプルなコールバック機構の実装サンプルを提示して回答に代えます.

JavaScript

1//簡単な非同期関数 2function simpleAsync(callback){ 3 let i = 0; 4 const h = setInterval(function(){ 5 console.log(i); 6 if(++i >= 10){ 7 clearInterval(h); 8 callback(); 9 } 10 }, 0); 11 console.log("callback function was scheduled."); 12} 13 14function useSimpleAsync(){ 15 simpleAsync(function(){ 16 console.log("callback function was called."); 17 }); 18} 19useSimpleAsync();

このようにコールバック関数はsetInterval関数等の非同期的に呼び出される処理内から呼び出す必要があります.

投稿2018/03/29 21:28

defghi1977

総合スコア4756

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

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

keys

2018/04/04 00:03

適切な回答、ありがとうございました。
guest

0

関数Aを実行したら、関数の中でループ処理が行われ、そのループが終わったら、関数Bを実行するというものです。

こういうことですかね。

setIntervalではなく、setTimeoutの方を使ってみました。

// 関数timerが関数Aに相当 // 関数timerの引数に渡すcallbackが関数Bに相当 function timer(callback) { var counter = 0; setTimeout(function tick(){ console.log("counter", counter); counter++; if(counter >= 10) { return callback(null, 'done'); } setTimeout(tick, 200); }, 200); } timer(function(error, result) { if (error) { return console.error(error); } console.log(result); }); > counter 0 > counter 1 > counter 2 > counter 3 > counter 4 > counter 5 > counter 6 > counter 7 > counter 8 > counter 9 > done

追記

今回、質問文に掲載されているコードが期待した順番で動かない理由は、
setIntervalが非同期実行されるためです。

setIntervalやsetTimeoutは非同期実行されるため、
同期実行されるものが先に呼ばれることになります。

以下はsetTimeoutを使った例です。

// 【非同期】遅延時間0秒でログ出力 setTimeout(function() { console.log('0 second delay'); }, 0); // 【非同期】遅延時間1秒でログ出力 setTimeout(function() { console.log('1 second delay'); }, 1000); // 【同期】100,000から0まで同期的にディクリメント var count = 100000; while(count--) { console.log('count down:', count); } //【同期】単純に'Hello'と出力 console.log('Hello'); // 出力結果: > count down: 99999 - 同期 > count down: 99998 - 同期 > (中略) - 同期 > count down: 2 - 同期 > count down: 1 - 同期 > count down: 0 - 同期 > Hello - 同期 > 0 second delay - 非同期 > 1 second delay - 非同期

投稿2018/03/30 00:10

編集2018/03/30 02:40
HayatoKamono

総合スコア2415

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問