Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 在侦听器中重试重新启动的调用_Angularjs_Restangular - Fatal编程技术网

Angularjs 在侦听器中重试重新启动的调用

Angularjs 在侦听器中重试重新启动的调用,angularjs,restangular,Angularjs,Restangular,官方重新启动语言文档提供了在ErrorInterceptor中重试请求的代码示例: var refreshAccesstoken = function() { var deferred = $q.defer(); // Refresh access-token logic return deferred.promise; }; Restangular.setErrorInterceptor(function(response, deferred, responseH

官方重新启动语言文档提供了在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
});
然而,正如它在评论中所说,第二次尝试不会触发任何拦截器,因为它直接使用$http


有没有办法让第二个请求也通过重新启动的管道并执行ErrorInterceptor

实际上,使用Restangular发出的请求使用了设计为只能解决一次的承诺。如果被拒绝,您不能重新发送

我真的不知道您是否想要一个可重用的
errorInterceptor
,但该服务的工作方式似乎不允许仅从
响应对象配置
重新构建重新启动的对象

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

你应该有你的理由,但我必须警告你,因为如果失败,如果它继续存在,你可能会以无限次的调用结束,因为重新启动的语言将始终调用
errorInterceptor

我为演示做了一些模拟,只需打开“网络”选项卡并单击按钮,您就会看到所有请求都在那里通过。

使用可能适合您的问题

假设您的异步函数是:

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);
    });
}
使用
重试
的示例:

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

你可能也会感兴趣。

现在回答这个问题已经太晚了,但是我找到了一个解决方案,所以我将在这里提到它作为可能的解决方案

下面的链接中有一个提示,提示您需要使用
restangularizeElement

我正在修复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
});

这样,若重复的请求导致任何错误,它将再次被重新启动的错误拦截器捕获

您可以替换
$http(response.config).then(responseHandler,deferred.reject)使用restApi调用。。使用$http拦截器而不是restanglar拦截器,即使使用restanglar。我更喜欢$http拦截器,因为像restangular这样的angularjs api包装器在内部使用$http…问题是拦截器中从
$http
切换到
restangular
。不要将
Restangular
与简单的rest调用混淆。我有这样一个场景:如果我得到错误代码约200,当我调用某个post服务时,我需要调用一个服务(如get),再次需要调用我得到错误代码200的同一个post服务