[AngularJS] $http, $resource のリクエスト処理を中断する方法

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

angularjs125title

車輪開発大好きおたいがです。こんにちは。( 挨拶 )

掲題について、つい最近まで実装方法を知らなかったので書いておきます。
( 今日まで必要とするシーンがなかったのですね )

$http サービスの場合

$http(config);

$http のリファレンスに記述されているのですが、config パラメータの timeout プロパティには number 型または Promise 型のオブジェクトをセットすることが可能です。

この Promise オブジェクトの親に相当する Deferred オブジェクトを resolve したときに、リクエスト処理が中断される仕様になっています。リクエスト処理が中断されると、リクエスト処理 ( $http, $resource ) が返す Promise オブジェクトの catch メソッドがコールされます。

実装例

var successHandler = function(data) {
…
};
var faultHandler = function(err) {
…
};
var finallyHandler = function() {
…
};
var canceller = $q.defer();
var promise = $http({
    'method'  : 'PUT',
    'url'     : '//hoge.s3-ap-northeast-1.amazonaws.com/…',
    'timeout' : canceller.promise,
    …
    'data'    : …
});
promise.then(successHandler);
promise['catch'](faultHandler);
promise.finally(finallyHandler);

//中断処理
ctrl.uploadCancelButtonClickHandler = function() {
    canceller.resolve();
};

$resource サービスの場合

$resource(url, [paramDefaults], [actions], options);

$resource の場合は、actions パラメータの timeout プロパティに Promise 型のオブジェクトをセットすることで $http と同じようにリクエスト処理を中断することが可能です。

$http, $resource をラップしたサービスを実装する場合の手段

$http($resource) の Promise オブジェクトと、timeout プロパティに設定した Promise オブジェクトの親 Deferred オブジェクトのペアを返却するようなメソッドを持つサービスを実装することが望ましいかと思われます。

実装例

(function() {
  'use strict';
  angular.module('sampleApp').factory('sampleService', function($http, $q) {
    var canceller = $q.defer();
    var promise = $http({
      'method'  : 'PUT',
      'url'     : '//hoge.s3-ap-northeast-1.amazonaws.com/…',
      'timeout' : canceller.promise,
      …
      'data'    : …
    });
    return {
      'canceller' : canceller,
      'promise'   : promise
    };
  });
}());

さいごに

たまたま、巨大ファイルをアップロードする画面の実装をすることになって知ったのですが、リファレンスはしっかり読まないとイカンですね。

参考

Canceling $http Requests in AngularJS
http://odetocode.com/blogs/scott/archive/2014/04/24/canceling-http-requests-in-angularjs.aspx