On route change, I need to abort ALL pending requests from previous route so that I don't run into problems of responses from previous route messing up data on my current route (it happens sometimes when responses from previous route take long time to finish).

在路由更改时,我需要中止来自先前路由的所有待处理请求,以便我不会遇到先前路由的响应问题,从而弄乱我当前路由上的数据(有时候,当前一路由的响应需要很长时间才能完成时) 。

I have thought about using http interceptor for this:

我曾考虑过使用http拦截器:

$httpProvider.interceptors.push(function($q) {
    return {
     'request': function(config) {

      },

      'response': function(response) {

      }
    };
  });

In the request function, I could modify the config.timeout with a promise as suggested here and store all the deferred objects in a global cache so that I could cancel all of them.

在请求函数中,我可以使用此处建议的promise修改config.timeout,并将所有延迟对象存储在全局缓存中,以便我可以取消所有这些。

The problem with this approach is that it may override config.timeout set in other places in the code.

这种方法的问题在于它可能会覆盖代码中其他位置设置的config.timeout。

I think another solution could be to cancel all ajax requests at XMLHttpRequest level, but I don't know how to do it.

我认为另一种解决方案可能是取消XMLHttpRequest级别的所有ajax请求,但我不知道该怎么做。

Any suggestions? Thanks.

有什么建议么?谢谢。

1 个解决方案

#1


6

As you say, timeout is the only API we have of use right now to cancel a running $http request. I think you're right on the money with an interceptor coupled with a cancel promise.

正如你所说,timeout是我们现在用来取消正在运行的$ http请求的唯一API。我认为你的拦截器加上取消承诺你的钱是正确的。

What you could do is attach the full deferred object on the $http request, and cancel all pendingRequests in your route change handler.

您可以做的是在$ http请求上附加完整的延迟对象,并取消路由更改处理程序中的所有pendingRequests。

Something like this could (perhaps*) work?

像这样的东西可能(或许*)有效吗?

angular.module('module').config(function ($httpProvider) {
  $httpProvider.interceptors.push(function ($q) {
    return {
      request: function (config) {
        if (!config.timeout) {
          config.cancel  = $q.defer();
          config.timeout = config.cancel.promise;            
        }

        return config;
      }
    }
  });
});

angular.module('module').run(function ($rootScope, $http) {
  $rootScope.$on('$stateChangeStart', function () {
    $http.pendingRequests.forEach(function (pendingReq) {
      if (pendingReq.cancel) {
        pendingReq.cancel.resolve('Cancel!');
      }
    });
  });
});

*: I say perhaps, because I had success with this approach, but it's seldom you find a silver bullet to something like this.

*:我或许也许说,因为我采用这种方法取得了成功,但很少能找到像这样的银弹。


edit

编辑

If you need to bypass the error handler of the cancelled promise, hook into responseError property and do manual labour there.

如果您需要绕过已取消的promise的错误处理程序,请挂钩到responseError属性并在那里进行手动操作。

angular.module('module').config(function ($httpProvider) {
  $httpProvider.interceptors.push(function ($q) {
    return {
      responseError: function (response) {
        if (response.config.timeout.$$state.value === 'Cancel!') {
          // debugger; 
          return $q.when('bypassed');
        }
      }
    }
  });
});

I'm starting to think that there is no generic/'cool' solution to reach the end result you desire. Treading some odd ground here : )

我开始认为没有通用/“酷”的解决方案来达到你想要的最终结果。在这里走一些奇怪的地方:)


edit2:

EDIT2:

Testing the above myself now. Returning $q.when('something') in the responseError will effectively bypass the error callback of the cancelled $http request. Let me know if it works out for you.

现在自己测试一下。在responseError中返回$ q.when('something')将有效地绕过已取消的$ http请求的错误回调。如果它适合您,请告诉我。

更多相关文章

  1. 【问题解决方案】ImportError: No module named 'pygal'
  2. Python 黏包及黏包解决方案
  3. 无法安装ndg-httpsclient或者我的解决方案错误
  4. Django 基础(一),项目创建、URL路由、数据库操作、模版
  5. Linux无法连接网络解决方案
  6. Media-S 简介(一个开源的DRM解决方案)
  7. AppScan安全问题解决方案
  8. PLSQL乱码解决方案
  9. 数据库不支持中文解决方案(mysql)

随机推荐

  1. android为文本框设置背景资源-shape
  2. Android简易实战教程--第三十九话《Chron
  3. .Net 转战 Android 4.4 日常笔记(5)--新软
  4. 小胖加入Android Fans的 大军了 呵呵
  5. 在android的java代码中自定义log
  6. Android热修复(一):底层替换、类加载原理总
  7. Android(安卓)长按电源键关机整个流程小
  8. 松下将在日本推出 7 寸和 10 寸企业用三
  9. Android 的网络编程
  10. init进程【4】——属性服务