【问题标题】:Cancelling pendingRequests is not working for angularJS 1.7.2 version取消 pendingRequests 不适用于 angularJS 1.7.2 版本
【发布时间】:2020-01-18 09:17:40
【问题描述】:

当再次调用相同的 api 时,我试图取消挂起的 api 调用。我有下拉 onChange 我正在调用我的 api ,这里 api 调用需要很多时间来返回数据,所以我取消了所有以前在 pendingRequest 数组中的调用并只保留最新触发的调用。请在下面查看我的代码

在我的控制器中

angular.forEach($http.pendingRequests,function(r){
        console.log(r.contractId);
        if (r.contractId && r.contractId !== selectedContract) {
           r.cancel.resolve('cancelled');
        }
 });

在这里,我通过将当前选择的合约与 pendingRequest 数组进行比较来检查挂起的请求是否是最新的。

这就是我编写服务的方式

getDashboardData:function(selectedContract) {
    var deferred = $q.defer();
    var cancel  = $q.defer();
    $rootScope.loaderOn=true;
    var url = 'my_url_here';
  $http.get(url, {
        ignoreLoadingBar: true,
        headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        },
        cancel:cancel, //this is of type $q.defer();
        contractId:selectedContract // here i assigned contrract id just to delete all pending api's other than current
    }).then(function(data){
        deferred.resolve(data.data);
            $rootScope.loaderOn=false;      
    },function(error){
          console.log(error);
          return deferred.reject(err);
      });

    return deferred.promise;
}

我想取消或拒绝挂起的 API 调用。任何帮助将不胜感激,谢谢。让我知道是否需要任何其他信息。请在这里纠正我。

【问题讨论】:

  • switchMap 使用 rxjs 将解决您的问题
  • 我使用的是 angularJS 而不是 angular 2
  • 对不起,但我不认为这是一个问题,因为我从未使用过 angularJS*。但是 afaik,rxjs 是满足您异步需求的实用工具,因此为此安装软件包应该没有问题
  • rxjs 中的地图是循环的吗?使用 angular foreacha 和 map 有什么区别?
  • 地图,是的,它是一样的。 map 返回一个数组,而 forEach 只遍历

标签: angularjs xmlhttprequest angular-promise deferred


【解决方案1】:
const request = new Map() // put this outside the main function

getDashboardData() { // call this on change
  const url = 'my_url_here';  // value should be constant
  const oldRequest = request.get(url) // get the last promise request 

  oldRequest.reject && oldRequest.reject('old request') // cancel's the last promise request
  // last promise request successCallback won't be called since the promise is already rejected

  $q((resolve, reject) => { // creates a new promise
    request.set(url, { resolve, reject }) // store resolve, reject
    return $http.get(url) // create api request
  })
  .then(successCallback) // on request success
  .catch(rejectedOrErrorCallaback)
}

你可以将它重新实现为这样的东西。 顺便说一句,根据文档。 $http.pendingRequests 主要用于调试目的。所以我认为这是一个远离使用的标志

【讨论】:

  • 如果您对我的回答有任何疑问,请随时提问。
  • 你完全误解了我的问题。
  • 编辑了我的答案。我得到你想要的,我给你的是一个想法/有点答案。你应该将你的代码重构为这个,或者找到一种方法来实现这样的事情。供参考。对服务器的 api 请求不会被取消,它会成功,但如果已经被拒绝,则不会在 successCallback 上被捕获
【解决方案2】:

我提到了$http 并且怀疑 $http.get 函数的配置对象中是否存在取消属性。您可以使用 timeout 属性并使用该值来取消现有请求。

我已将取消属性替换为超时。

我希望下面的代码有所帮助。

// Declare the below objects in service level not inside getDashboardData function 
var deferredObj = '';
var existingRequest = '';

getDashboardData: function(selectedContract) {
var deferred = $q.defer();

// Below condition will check to cancel the existing request
if (existingRequest) {
   existingRequest = '';
   deferredObj.resolve();
   deferredObj = '';
} else {
    deferredObj = $q.defer();
}
$rootScope.loaderOn=true;
var url = 'my_url_here';
existingRequest = $http.get(url, {
    ignoreLoadingBar: true,
    headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
    },
    **timeout : deferredObj.promise**, //this is of type $q.defer();
    contractId:selectedContract // here i assigned contrract id just to delete all pending api's other than current
}).then(function(data){
    deferred.resolve(data.data);
        $rootScope.loaderOn=false;      
},function(error){
      console.log(error);
      return deferred.reject(err);
  });

return deferred.promise;
}

【讨论】:

  • 嗨,开发者,昨天我发现了,是的,你是对的,我错过了超时,所以它采用默认超时,因此它没有取消通话。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-10
  • 2015-10-01
  • 2021-12-04
  • 1970-01-01
相关资源
最近更新 更多