【问题标题】:$http simultaneous duplicate API call, return promise$http 同时重复 API 调用,返回 promise
【发布时间】:2018-05-17 18:45:58
【问题描述】:

在我的应用中,我们使用微服务结构,为此我们添加了缓存。

但是有一种情况是多个相同的请求被触发,并且请求同时被触发,所以缓存似乎也不起作用。 我希望对于重复请求,它应该发送先前请求的承诺。

还有很多服务,所以给每个服务添加承诺是行不通的。是否有任何地方可以处理重复请求并在一个共同的地方传递先前的请求承诺。可能是通过使用装饰器或 http 拦截器。

服务调用

testService.getTestByIds = function (
                                testIds,
                                contextInfo) {
         var params = {
                 testId: requestDefinitionIds
           };
         params = CommonProvider.apppendContextParams(contextInfo, params,testInfoCache);
          return $http.get(SERVICE_URL + 'tests', {
                                cache: testInfoCache,
                                params: params,
                                transformResponse: CommonProvider.appendTransformer($http.defaults.transformResponse, function (value) {
                                    return transformTestResponse(value);
                                })
                            });
                        };

【问题讨论】:

  • 这个场景回答起来很简短,是不是你有嵌套的 API 调用?还是有比赛条件? $q 服务至少可以解决这些问题的一半。
  • 它的竞争条件。将有多个 getById 调用相同的 id。我无法在控制器中处理这个。所以我可以改变服务或拦截器
  • 我会选择装饰器,这是包装 $http 服务并修改其行为的方式。示例一:michalostruszka.pl/blog/2013/07/31/double-requests;示例 2:jsfiddle.net/referee/hh30bh0q
  • @LenilsondeCastro 我不太擅长装饰器。所以我尝试使用 jsfiddle 中给出的第二个示例,但它给出了错误Cannot read property 'transformResponse' of undefined。我在服务中使用了transformResponse
  • @LenilsondeCastro 我还添加了我的服务代码以供参考

标签: javascript angularjs http angular-http-interceptors angular-cache


【解决方案1】:

我假设你的意思是在客户端缓存,你可以尝试这样的事情:

const activeRequest = 
  () => {
    const requests = {};
    return (url,params) => {
      const promise = requests[url+JSON.stringify(params)];
      if(promise){
        return promise;
      }
      return requests[url+JSON.stringify(params)] = 
        //not sure what you use for angular, maybe $http for angular1
        fetch(url,params)
        .then(
          x=>{
            requests[url+JSON.stringify(params)] = undefined;
            return x;
          }
        )
    }
  }

【讨论】:

  • 逻辑似乎是正确的。但我不能在控制器中改变它。那么如何将这些更改应用于服务方法
  • @Anita 你打电话给$http吗?如果需要,您可以调用activeRequest(作为服务注入)并让activeRequest 调用$http,而不是调用$http。
猜你喜欢
  • 1970-01-01
  • 2021-04-21
  • 1970-01-01
  • 1970-01-01
  • 2020-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多