【问题标题】:Route resolve going through even on a bad request即使在错误的请求下,路由解析也会通过
【发布时间】:2015-12-11 13:49:05
【问题描述】:

在创建这样的视图之前,我需要解决两个服务调用

$stateProvider
    .state('parent', {
        url: '/parent',
        abstract: true,
        resolve: {
            resolveService: function($q, personService, jobService) {
                return $q.all({
                    persons: personService.getPersons(),
                    jobs: jobService.getJobs()
                })
            }
        }
    })

    .state('parent.child', {
        url: '/child'
    })

一个服务看起来像这样

 function getPersons() {
    var req = {
        method: 'POST',
        url: 'http://myPersonApi'
    }

    return $http(req)
    .then(getPersonsComplete)
    .catch(getPersonsFailed)

    function getPersonsComplete(response) {
        return response.data.persons;
    }

    function getPersonsFailed(error) {
        //log error
        return error;
    }
}

我试了一下,但在dev 中出现CORS 错误,这是完全可以预料的,但奇怪的是即使$http 被拒绝,路由也得到了解决。

我进行了调试,发现我得到了一个HTTP status code 405,并且运行了getPersonFailed 函数,但仍然解决了$q.all。我尝试将其更改为 $q.reject,然后它按预期工作,但路线从未实现。

注意$http 调用的错误对象是status: 0statusText: ""

$http promise 的处理方式与$q 的处理方式不同吗?

【问题讨论】:

标签: angularjs angular-ui-router angular-promise


【解决方案1】:

我认为这是因为您的 catch 处理程序通过返回一个字符串来解决承诺。尝试明确拒绝 catch 中的承诺,或者干脆移除 catch。

function getPersonsFailed(error) {
    return $q.reject(error);
}

或者,您可以将其放入 catch 中,这也会导致 promise 被拒绝

function getPersonsFailed(error) {
    throw(error);
}

我认为这是有用的阅读:
https://gist.github.com/domenic/3889970

【讨论】:

  • 在不涉及 $q 的情况下我们可以返回失败状态中的任何内容吗? $http 应该如何正常工作?我希望当 Promise 链中的 Promise 被拒绝时,它会向后冒泡,而不必手动拒绝。
  • catch 基本上让你有机会拦截错误并决定你想用它做什么。例如,可能存在您在 http 尝试失败后使用缓存响应手动解析的情况。如果您希望它在没有任何重新抛出的情况下冒泡,那么就不要包含捕获。
【解决方案2】:

经过一番研究,我发现了你为什么会出现这种奇怪的行为。

要知道的是,promise.catch()getPersonsFailed 函数的末尾返回一个全新的承诺,即 resolved

为避免这种情况,您需要返回一个被拒绝的承诺。

function getPersonsFailed(error) {
    //Do some logic here to handle your error in your service
    return $q.reject(error);
}

您也可以像这样将您的解决方案写得更小(但也许您的语法是故意的)

    resolve: {
       persons: personService.getPersons(),
       jobs: jobService.getJobs()
    }

您的服务器响应将在您的控制器中注入 personsjobs

如果您在 .catch() 方法中没有做任何其他事情,我建议您直接删除它。

希望对您有所帮助。

【讨论】:

  • 如果我这样解决,函数会像 $q.all 一样并行运行吗?
  • @IngóVals 是的,解决如果基本上在你给他的对象上调用 $q.all() 然后添加每个属性的解析结果作为依赖注入
猜你喜欢
  • 2015-12-12
  • 1970-01-01
  • 2019-02-08
  • 1970-01-01
  • 2014-06-22
  • 2019-12-14
  • 2016-06-21
  • 1970-01-01
  • 2018-08-16
相关资源
最近更新 更多