【问题标题】:Retry a Restangular call in an interceptor在拦截器中重试 Restangular 调用
【发布时间】:2014-09-08 13:53:07
【问题描述】:

restangular 官方文档provides 这个代码示例在ErrorInterceptor 中重试请求:

var refreshAccesstoken = function() {
    var deferred = $q.defer();

    // Refresh access-token logic

    return deferred.promise;
};

Restangular.setErrorInterceptor(function(response, deferred, responseHandler) {
    if(response.status === 403) {
        refreshAccesstoken().then(function() {
            // Repeat the request and then call the handlers the usual way.
            $http(response.config).then(responseHandler, deferred.reject);
            // Be aware that no request interceptors are called this way.
        });

        return false; // error handled
    }

    return true; // error not handled
});

但是,正如它在 cmets 中所说,第二次尝试不会触发任何拦截器,因为它直接使用 $http。

有没有办法让第二个请求也通过 Restangular 管道并执行 ErrorInterceptor?

【问题讨论】:

  • 你可以用restApi调用替换$http(response.config).then(responseHandler, deferred.reject);。使用$http拦截器而不是restangular拦截器,即使是restangular。我更喜欢 $http 拦截器,因为所有 angularjs api 包装器(如 restangular)在内部都使用 $http ...
  • 问题是关于在拦截器中从$http切换到Restangular。不要将Restangular 与简单的休息电话混淆。

标签: angularjs restangular


【解决方案1】:

实际上,使用 Restangular 发出的请求使用的 Promise 被设计为只解析一次。如果被拒绝,您将无法重新发送。

我真的不知道你是否想要一个可重复使用的 errorInterceptor,但服务的工作方式似乎不允许简单地重新构建一个 Restangular 对象 response object config

您可以做的一件事是保存对您的对象的引用,然后在拦截器中使用它。

你应该有你的理由,但我必须警告你,因为在失败的情况下,如果它持续存在,你可能会得到一个无限调用,因为 Restangular 将始终调用 @ 987654324@.

我已经模拟了一个小 Plunkr 用于演示,只需打开您的网络选项卡并单击按钮,您应该会看到所有请求都通过那里。

【讨论】:

  • 我有一个场景,比如如果我收到大约 200 的错误代码,当我调用一些 post 服务时,我需要调用一个服务(如 get),再次需要调用相同的 post 服务,其中我得到了错误代码 200
【解决方案2】:

使用async.retry 可能适合您的问题。

假设你的异步函数是:

function apiCall(callback) {
  Restangular.all('items').getList()
    .then(function (res) {
      // all is OK
      callback(null, res);
    })
    .catch(function (err) {
      if (err.status === 403) {
        // this one will bring async to retry apiMethod
        return callback(err);
      }
      // others errors codes will not call apiMethod again
      callback(null);
    });
}

使用retry 的示例:

// async will try it 3 times
async.retry(3, apiCall, function(err, result) {
  // do something with the result
});

async.doUntil 你也会感兴趣。

【讨论】:

    【解决方案3】:

    答案为时已晚,但是我找到了解决方案,所以我将在此处提及它作为可能的解决方案。

    以下链接中有提示说您需要使用restangularizeElement

    https://github.com/mgonto/restangular/issues/1022

    我正在修复restangular官方示例如下:

    Restangular.setErrorInterceptor(function(response, deferred, responseHandler) {
      if(response.status === 403) {
        refreshAccesstoken().then(function() {
          // instead of using $http, I will use restangularizeElement as follow
          // I still have no idea how is the best method to repeat the request after restangularized it. I am repeating it with a simple get
          var request = Restangular.restangularizeElement('', response.data, url);
          request.get().then(function() {});
        });
        return false; // error handled
      }
    
      return true; // error not handled
    });
    

    这样,如果重复请求导致任何错误,它将再次被restangular错误拦截器捕获。

    【讨论】:

      猜你喜欢
      • 2015-03-15
      • 2014-05-29
      • 2015-04-16
      • 2015-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多