Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
AngularJS TIPS

AngularJS TIPS

指定された時間の経過で処理を実行するには?($interval/$timeout)

2016年1月4日

ミリ秒単位で処理を実行できる、いわゆる「タイマー」である$intervalサービスの基本的な使い方を解説。また、一定時間後に処理を実行する$timeoutサービスについても説明する。

  • このエントリーをはてなブックマークに追加

 $intervalサービスは、指定された時間(ミリ秒)単位に任意の処理を実行するためのサービスです。例えば以下は、1000ミリ秒おきに表示時刻を更新する例です。

HTML
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8" />
<title>AngularJS TIPS</title>
</head>
<body ng-controller="MyController">
<div>{{message}}</div>
<button ng-click="onclick()">ストップ</button>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
<script>
angular.module('myApp', [])
  .controller('MyController',
  ['$scope', '$interval', function($scope, $interval) {
    // 11000ミリ秒単位に処理を実行
    var t = $interval(function() {
      $scope.message = '現在時刻:' + (new Date()).toLocaleTimeString();
    }, 1000);

    // 2[ストップ]ボタンでタイマー処理を中止
    $scope.onclick = function() {
      $interval.cancel(t);
    };
  }]);
</script>
</body>
</html>
リスト1 現在時刻をリアルタイムに更新する例(interval.html)
1秒おきに表示時刻を更新

1000ミリ秒後……

1秒おきに表示時刻を更新
1秒おきに表示時刻を更新

 $intervalサービスの構文は、以下の通りです。

[構文]$intervalサービス

$interval(func, delay [,count [,invoke]])
  • func: 実行する処理
  • delay: 処理の間隔(ミリ秒)
  • count: 実行すべき回数(デフォルトは0(無限))
  • invoke: $applyメソッド*1配下で引数funcを実行するか(デフォルトはtrue
  • *1 $applyメソッドについては後日別稿で解説予定です。

 引数countinvokeを除けば、JavaScript標準のsetIntervalメソッドと同等です。では、setIntervalメソッドでもよいではないかと思われるかもしれませんが、これは不可です。

 試しに、1setIntervalメソッドで置き換えてみるとどうでしょう。エラーにはなりませんが、時刻が表示されなくなります。AngularJSが、スコープ変数の更新を検出できていないのです。

 AngularJSでは、「イベントが発生した」などのタイミングでスコープの変更を確認し、変更があった場合にはこれをページに反映させます。しかし、標準のsetIntervalメソッドでは、イベントそのものが発生しませんので、その中での更新も反映されないというわけです。言うなれば、$intervalサービスとは、スコープ更新に伴うページへの反映機能を備えたsetIntervalメソッドなのです。

 $intervalメソッドによるタイマー処理を中止しているのが2です。$intervalメソッドは、戻り値としてタイマー処理を管理するPromiseオブジェクトを返します。タイマー処理をキャンセルするには、$intervalサービスのcancelメソッドに対して、Promiseオブジェクトを渡すだけです。

一定時間後に処理を実行する$timeoutサービス

 指定時間単位に処理を実行する$intervalサービスに対して、指定された時間が経過した後に処理を実行するのは$timeoutサービスの役割です。構文は、$intervalサービスとも共通なので、特筆すべき点はありません(引数countのみ利用できません)。

[構文]$timeoutサービス

$timeout(func, delay [,invoke])

  • func: 実行する処理
  • delay: 処理の間隔(ミリ秒)
  • invoke: $applyメソッドの配下で引数funcを実行するか(デフォルトはtrue

 試しに、先ほどのリスト1-1$timeoutで置き換えてみると、確かにサンプル起動から1秒後に現在時刻が表示されます(一度だけで以降の更新はありません)。

JavaScript
angular.module('myApp', [])
  .controller('MyController',
  ['$scope', '$timeout', function($scope, $timeout) {
    var t = $timeout(function() {
      $scope.message = '現在時刻:' + (new Date()).toLocaleTimeString();
    }, 1000);
  }]);
リスト2 リスト1を$timeoutサービスで置き換えたコード(timeout.html)
起動から1秒後に現在時刻を表示
起動から1秒後に現在時刻を表示

タイマー関数に引数を渡す

 AngularJS 1.4以降では、タイマー関数($interval$timeoutサービスの引数func)に対して、引数を渡すことも可能です。タイマー関数に渡すべき引数は、$interval$timeoutサービスの最後の引数として指定します。

 例えば以下は、先ほどのリスト1で先頭の文字列「現在時刻:」を引数で置き換えられるようにした例です。

JavaScript
var handler = function(prefix) {
  $scope.message = prefix + (new Date()).toLocaleTimeString();
};

var t = $interval(handler, 1000, 0, true, '現在時刻:');
リスト3 $intervalサービスのタイマー関数に引数を渡す例(interval2.html)

 太字の部分は可変長引数なので、タイマー関数が複数の引数を受け取る場合には、$interval$timeoutサービスにも必要な数だけ列挙できます。

処理対象:タイマー カテゴリ:サービス
API:$interval|timeout カテゴリ:ng(コアモジュール) > service(サービス)

※以下では、本稿の前後を合わせて5回分(第36回~第40回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

AngularJS TIPS
36. サーバーサイドとHTTP POSTで非同期通信するには?($http)

AngularJSでHTTP POSTで非同期通信する方法を説明。また、送信データをJSONではなくjQuery形式にする方法や、PHPでJSONデータをデコードする方法も紹介する。

AngularJS TIPS
37. JSON形式のWeb APIにアクセスするには?($http)

Web APIと通信する際に問題となるクロスドメイン制約を回避するために使われるテクニック「JSONP」を、AngularJSで実現するための基本的な方法を説明する。

AngularJS TIPS
38. 【現在、表示中】≫ 指定された時間の経過で処理を実行するには?($interval/$timeout)

ミリ秒単位で処理を実行できる、いわゆる「タイマー」である$intervalサービスの基本的な使い方を解説。また、一定時間後に処理を実行する$timeoutサービスについても説明する。

AngularJS TIPS
39. 配列/オブジェクトの内容を列挙するには?(forEach)

angular.forEachメソッドを使って、配列の要素やオブジェクトのメンバーを列挙する方法を解説する。

AngularJS TIPS
40. クッキーを読み書きするには?($cookies)

AngularJSが提供する機能を利用してクッキーを読み/書き/削除する方法を解説。また、登録済みの全てのクッキー情報をまとめて取得する方法も説明する。

サイトからのお知らせ

Twitterでつぶやこう!