【问题标题】:Preventing similar POST requests with AngularJS使用 AngularJS 防止类似的 POST 请求
【发布时间】:2015-04-17 23:22:11
【问题描述】:

我目前正在构建一个包含多个小部件的仪表板页面。这些小部件通过 REST 调用 ($resource) 检索它们的数据。一些小部件发出类似的调用,我不想 DDOS 我们的服务器,所以我正在寻找一种方法,只进行一次调用并以相同的响应解决所有类似的请求。

由于我仅限于使用 POST 请求,因此我无法使用 $resource 提供的缓存选项。这似乎完全符合我的要求,但仅适用于 GET 请求。

我正在考虑使用 http 拦截器对类似的 POST 请求进行排队,只触发其中一个并在第一个得到响应时将它们全部解决。

但是,我似乎无法将各个部分拼凑在一起,因此感谢您的帮助。我愿意接受其他选择。

亲切的问候, 蒂姆

【问题讨论】:

    标签: angularjs promise ngresource angular-http-interceptors


    【解决方案1】:

    AngularJS 中的服务是单例的,因此解决方案是将响应作为变量存储在服务中。然后下次你做请求时,之前检查变量是否为空,如果不是,你将它包装在一个承诺中并返回它。如果它为 null,那么您执行请求,并存储响应以供下一次调用。

    您也可以在请求服务或拦截器服务中使用它。

    希望我能帮上忙!

    【讨论】:

    • 感谢您的建议,但我想更进一步,因为如果 4 个小部件位于同一页面上并且尚未填充缓存,此解决方案仍将进行 4 次调用。我想要 Angular 为 GET 请求做的事情。源代码注释:如果对同一个 URL 有多个 GET 请求应该使用同一个缓存进行缓存,但缓存尚未填充,则只会向服务器发出一个请求,其余请求将使用第一个请求的响应。
    • @TimKetelaars 诀窍是缓存承诺而不是结果。如果您的问题是关于这种模式的,请特别告诉我,我会添加答案。
    • 我设法将类似的 Promise 缓存在一个数组中,并在第一个 Promise 解决后解决所有这些 Promise。但是,我只能在服务中执行此操作,但希望它能够降落在拦截器中。我不知道如何结合这个,因为 $httpProvider 拦截器的请求方法不返回一个承诺,而是一个配置对象。旁注:拦截器是实现这个的正确位置吗?
    • 嗨,蒂姆,您最终找到解决方案了吗?我很想看到一个sn-p的代码!对于拦截器,我不知道,在我看来它是正确的地方,但我不清楚如何去做。也许您可以尝试结合使用 $httpProvider.request 方法来拦截和 $httpProvider.response 方法来发送结果。祝你好运!
    • 我现在使用服务方法。这个想法是使用您提到的 $httpProvider 方法,但还没有找到一种方法来做到这一点。片段:`var similarRequests = null; function getData(requestData) { var deferred = $q.defer(); if (similarRequests === null) { similarRequests = new Array(); aService.getData(requestData).then(function (data) { deferred.resolve(data); angular.forEach(similarRequests, function (request) { request.resolve(data); }); similarRequests = null; }); } else { similarRequests.push(deferred); } return deferred.promise; };
    【解决方案2】:

    重构您的小部件以依赖服务(单例)。 该服务应该通过 XHR 轮询服务器,或者通过 websocket 获取服务器推送以获取更新。

    如果是轮询,请查看服务器端缓存和 etag。

    【讨论】:

      猜你喜欢
      • 2014-06-17
      • 2018-03-31
      • 2017-03-03
      • 2018-09-14
      • 1970-01-01
      • 1970-01-01
      • 2013-08-16
      • 2017-08-24
      • 1970-01-01
      相关资源
      最近更新 更多