web-dev-qa-db-ja.com

ファクトリまたはサービス内で$ http.get()を中止するタイムアウトを設定するにはどうすればよいですか?

私のfactoryに次のメソッドgetData(url)があります。これは$http.get(url)を使用してURLからデータを取得します

angular
  .module('az-app')
  .factory('WebServiceFactory', function ($http, $q) {

   var WebServiceFactory = this;


   WebServiceFactory.getData = function (url) {

      var deferred = $q.defer();

      $http.get(url)
        .then(
        function (response) {

          deferred.resolve({
            data: response
          });

        }, function (rejected) {

          deferred.reject({
            data: rejected
          });
        }
      );
      //Promise to be returned
      return deferred.promise;
    }

正常に動作しますが、http.getを中止するか、promiseを拒否して、次のメソッドを持つcontrollerからエラーメッセージを表示できるようにする必要があります。

var getSpecialties = function (type) {
  doctorsCtrl.showLoading();

  var url = "example.com";

  WebServiceFactory.getData(url)
    .then(
    function (result) {
      doctorsCtrl.hideLoading();


      var specialtiesArray = result.data.data;

      StorageFactory.specialties = specialtiesArray;
      doctorsCtrl.specialties = StorageFactory.specialties

      //I WANT TO TRIGGER THIS REJECTED FUNCTION when timeout time is finished
    }, function (rejected) {
      doctorsCtrl.hideLoading();
      doctorsCtrl.showAlert();
    }
  );
}
7
Jeka

サービス $httpは、configオブジェクトで、必要なものに応答するtimeoutプロパティを受け入れます。 documentation 、特にconfigオブジェクトに関する部分を見てください。

timeout – {number | Promise} –ミリ秒単位のタイムアウト、または解決時にリクエストを中止するpromise。

また、promiseを非効率的な方法で使用していることに注意してください。以下はpromise antipatternです。

WebServiceFactory.getData = function (url) {

 var deferred = $q.defer();

 $http.get(url)
   .then(
   function (response) {

     deferred.resolve(...);

   }, function (rejected) {

     deferred.reject(...);
   }
 );
 //Promise to be returned
 return deferred.promise;
}

あなたは単純に持つことができます:

WebServiceFactory.getData = function (url) {
    return $http.get(url);
}

3秒のタイムアウトでは、次のようになります。

サービス:

WebServiceFactory.getData = function (url) {
    return $http.get(url, {timeout: 3000});  // <-- timeout applies ONLY for this call
}

コントローラー:

WebServiceFactory.getData(url).then(
    function (result) {
      doctorsCtrl.hideLoading();
      doctorsCtrl.specialties = StorageFactory.specialties = result.data;
    }, function (rejected) {
      doctorsCtrl.hideLoading();
      doctorsCtrl.showAlert();
    }
  );

successerrorの両方の場合にhideLoadingを呼び出していることにも注意してください。チェーンされたfinallyハンドラーで一度呼び出すことができます:

// ...
.finally(function () {
    doctorsCtrl.hideLoading();
}
10