如何设置超时以中止工厂或服务中的 $http.get()? [英] How to set a timeout to abort an $http.get() inside a factory or service?

查看:37
本文介绍了如何设置超时以中止工厂或服务中的 $http.get()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的工厂中有以下方法getData(url),它使用$http.get(url)从一个网址

角度.module('az-app').factory('WebServiceFactory', function ($http, $q) {var WebServiceFactory = this;WebServiceFactory.getData = 函数(网址){var deferred = $q.defer();$http.get(url).然后(功能(响应){deferred.resolve({数据:响应});}, 函数(被拒绝){延迟.拒绝({数据:拒绝});});//承诺返回返回 deferred.promise;}

它工作正常,但我需要中止 http.get 和/或拒绝承诺,以便我可以显示来自具有此方法的控制器的错误消息:

var getSpecialties = 函数(类型){医生Ctrl.showLoading();var url = "example.com";WebServiceFactory.getData(url).然后(功能(结果){医生Ctrl.hideLoading();var specialtiesArray = result.data.data;StorageFactory.specialties = specialtiesArray;医生Ctrl.specialties = StorageFactory.specialties//我想在超时时间结束时触发这个被拒绝的函数}, 函数(被拒绝){医生Ctrl.hideLoading();医生Ctrl.showAlert();});}

解决方案

服务 $http 在 config 对象中接受一个 timeout 属性来回答你的问题需要.看看文档,特别是关于config对象的部分:

<块引用>

timeout – {number|Promise} – 以毫秒为单位的超时时间,或承诺在解决时应中止请求.

另外,请注意您正在以一种低效的方式使用 Promise.以下是一个 promise 反模式:

<块引用>

WebServiceFactory.getData = function (url) {var deferred = $q.defer();$http.get(url).然后(功能(响应){deferred.resolve(...);}, 函数(被拒绝){deferred.reject(...);});//承诺返回返回 deferred.promise;}

你可以简单地:

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

如果超时为 3 秒,则为:

服务:

WebServiceFactory.getData = function (url) {返回 $http.get(url, {timeout: 3000});//<-- 超时仅适用于此调用}

控制器:

WebServiceFactory.getData(url).then(功能(结果){医生Ctrl.hideLoading();医生Ctrl.specialties = StorageFactory.specialties = result.data;}, 函数(被拒绝){医生Ctrl.hideLoading();医生Ctrl.showAlert();});

另请注意,在 成功错误 的情况下,您都在调用 hideLoading.您可以在链式 finally 处理程序中调用它一次:

//....finally(函数(){医生Ctrl.hideLoading();}

I have the following method getData(url) in a my factory which uses $http.get(url) to get data from an 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;
    }

It works fine but I need to abort the http.get and/or reject the promise so I can display an error message from my controller which has this method:

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();
    }
  );
}

解决方案

The service $http accepts, in the config object, a timeout property that answers to what you need. Have a look at the documentation, especially the part about the config object:

timeout – {number|Promise} – timeout in milliseconds, or promise that should abort the request when resolved.

Also, notice that you're using promises in an inefficient way. The following is a 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;
}

You could have simply:

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

With a timeout of 3 seconds it would be:

Service:

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

Controller:

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

Notice also that you're calling hideLoading both in case of success and error. You can call it once, in a chained finally handler:

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

这篇关于如何设置超时以中止工厂或服务中的 $http.get()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆