メニューを閉じる

テクノデジタルグループ

メニューを開く

2018.01.31

プログラミング

setIntervalとsetTimeoutの非同期プログラミング

Canadian Devです。今回はJavaScriptの非同期プログラミングのベイシックドリルに取り組んでみたいと思います。

ドリルの内容:タイプライター

タイプライターみたいに、文章をブラウザに1文字ずつ表示して、一つの文が終わったら1秒の隙間を開けてから次の文に進む。

setIntervalの紹介

JavaScriptsetIntervalというファンクションを使うとすぐにできます。”Interval”という言葉は日本語で「間隔」という意味で、「一定の間隔を置いて」ファンクションを実行するときに使います。それで、setIntervalは二つの引数を受けるのです。1番目の引数が実行したいファンクションで、2番目の引数が間隔の長さを表す整数です。

var string = "Hello!";
var index = 0;
var characterSequence = setInterval(function() {
 $('div#terminal-screen').append(string[index]);
 index++;
 if (index >= string.length) clearInterval(characterSequence);
}, 50);

上記のファンクションによると、characterSequenceという変数にsetIntervalというファンクションが指定されます。そのファンクションの1番目の引数で実行したい内容を指定します。string[index]の文字をdiv#terminal-screenに表示してindexを増加するファンクションです。それに、stringの最後の文字になるとclearIntervalでファンクションを止める条件を付けます。例1を参考してください。

setIntervalと配列のループで起きる問題

次に、”Hello!だけではなく、いくつかの文が入った配列をsetIntervalで実行してみましょう。下記のコードはどうでしょうか?

var stringArray = ["Hello!", "How are you?", "Goodbye."];
stringArray.forEach(function(string) {
 var index = 0;
 var characterSequence = setInterval(function() {
  $('#terminal-screen').append(string[index]);
  index++;
  if (index >= string.length) clearInterval(characterSequence);
 }, 50);
})

最初のコードとほぼ一緒で、配列をループして繰り返すたびにsetIntervalを実行させます。でも、このコードを実行すると、アウトプットが”Hello! How are you? Goodbye.”ではなくて、”HHGeoolwol doab!ryee .you?”になってしまいます(例2。それはJavaScriptの非同期動作のためです。setIntervalをループすると一回で実行することになります。その非同期のsetIntervalが次々と実行するようにどう処理すればいいでしょう?

setTimeoutと一緒に使ったら?

この問題に解決法がいろいろあります。配列を一つのストリングに結合してもいいし、コールバックを使う処理もありです。でも、setTimeoutで処理したらどうですか?setTimeoutはファンクションの実行する時間を明白にします。setTimeoutは二つの引数を受けます。一つ目は相変わらず実行したいファンクションですが、二つ目はsetIntervalと違って、ファンクションが実行するのにどれぐらい遅延するかという時間設定です。setIntervalと違って、一回しか実行されません。ループの中にsetTimeoutを使うと、配列に入ったストリングが次々と出るようにできます。下記のコードを見てみましょう。

var stringArray = ["Hello!", "How are you?", "Goodbye."]
var timeDelay = 0;
stringArray.forEach(function(string) {
 var index = 0;
 setTimeout(function() {
  var characterSequence = setInterval(function() {
   $('#terminal-screen').append(string[index]);
   index++
   if (index >= string.length) clearInterval(characterSequence);
  }, 50);
 }, timeDelay);
 timeDelay += string.length*50 + 1000;
});

setTimeoutの1番目の引数は先のsetIntervalのファンクションで、2番目の引数はtimeDelayという遅延時間の変数になります。配列をループするたびにそのtimeDelayという変数にsetIntervalという時間と1秒の遅延時間が追加されます(string.length*50 + 1000)。つまり、最初に実行する時間を設定します(例3)。

setTimeoutとsetIntervalを使いましょう

setTimeoutとsetIntervalを使うと自分が好むタイミングでイベントを実行することができます。面白くて効果的なUIがたくさん作ることができるでしょう。どちらも便利で使いやすいファンクションですが、非同期動作のことで注意しましょう。


【記事への感想募集中!】

記事への感想・ご意見がありましたら、ぜひフォームからご投稿ください!
  • こんな記事が読んでみたい、こんなことが知りたい、調べてほしい!という意見も募集中!
  • いただいた感想は今後の記事に活かしたいと思います!

感想フォームはこちら


【テクノデジタルではエンジニア/デザイナーを積極採用中です!】

下記項目に1つでも当てはまる方は是非、詳細ページへ!
  • 自分でアプリを作ってみたい
  • ITで世の中にワクワクを生み出したい
  • 使いやすさ、デザインにこだわったWebサイトを開発したい

採用情報の詳細はこちら


Qangaroo(カンガルー)

  • 徹底した見やすさと優れた操作性で、テストの「見える化」を実現。
  • テストの進捗が見える。開発がスマートに進む。
  • クラウド型テスト管理ツール『Qangaroo(カンガルー)』

【テクノデジタルのインフラサービス】

当社では、多数のサービスの開発実績を活かし、
アプリケーションのパフォーマンスを最大限に引き出すインフラ設計・構築を行います。
AWSなどへのクラウド移行、既存インフラの監視・運用保守も承りますので、ぜひご相談ください。
詳細は下記ページをご覧ください。

https://www.tcdigital.jp/infrastructure/

最近の記事