javascript - 检测 Angular JavaScript promise 链中是否存在下一个处理程序

标签 javascript angularjs promise angular-http-interceptors

给定以下两个 $resource 示例:

var exampleOne = $resource('/path').save(objectOne);
exampleOne.$promise.then(function (success) {}, function (error) {});

var exampleTwo = $resource('/path').save(objectTwo);
exampleTwo.$promise.then(function (success) {});

[注意:示例二不包含错误处理程序]

还有一个位于所有 $http 请求之下的拦截器:

var interceptor = ['$location', '$q', function ($location, $q) {
   function error(response) {
       if (response.status === 400) {
           return $q.reject(response);
       }
       else {
           $location.path('/error/page');
       }
       return $q.reject(response);
   }

   return {
       'responseError': error
   };
}

$httpProvider.interceptors.push(interceptor);

当示例资源 $promise.then() 不包含错误回调时,如何让拦截器不拒绝?如果回调存在于 exampleOne 中,那么我希望拒绝,但如果不存在于 exampleTwo 中,那么我希望重定向到错误页面,从而将条件更改为类似:

if (response.status === 400 && $q.unresolvedPromises.doIndeedExist()) { ...

为什么?因为在我的项目中只有某些情况需要以用户友好的方式处理 400,因此我想消除许多重复的错误回调或不得不在拦截器中放置一个不常见情况的列表。我希望拦截器能够根据 promise 链中另一个处理程序的存在做出决定。

最佳答案

简单地说这是不可能的,您无法检测到将来是否有人会附加处理程序,就像您无法判断您何时抛出 在函数中,它是否会在外部被捕获。 然而,你想做的都能做

这不是一个“菜鸟问题”,而且非常基础:

 function foo()
    throw new Error(); // I want to know if whoever is calling `foo`
                       // handles this error
 }

首先,你可以做什么

简单的说第一种情况:

 exampleOne.$promise.then(function (success) {}, function (error) {});

您得到的是总是实现的 promise 。但是,在第二种情况下, promise 可能会被拒绝。使用拒绝处理程序处理拒绝就像实际代码中的 catch - 一旦你处理了它,它就不再被拒绝。

就个人而言,我不会在这里使用拦截器,而是使用资源使用模式,因为它的意图更清晰,您可以将它包装在一个函数中,这样它就不需要作用域,但我不太喜欢这个想法。这是我要做的

attempt(function(){
    return $resource('/path').save(objectTwo).$promise.
           then(function (success) {});
});

function attempt(fn){
    var res = fn();
    res.catch(function(err){
        // figure out what conditions you want here
        // if the promise is rejected. In your case check for http errors
        showModalScreen();
    }
    return res; // for chaining, catch handlers can still be added in the future, so
                // this only detects `catch` on the function passed directly so 
                // we keep composability
}

现在,一个无法完成的简短证明

为了好玩,让我们来证明一下。

假设我们得到程序 M 的代码,我们创建一个新的 promise p 并替换 M 中的每个 return 语句和 throw M 中带有 return p.catch(function(){}) 的语句并添加一个 return p.catch(function(){}),现在是一个处理程序将被添加到 p 当且仅当运行 M 终止时。所以简而言之 - 给定代码 M 我们已经构建了一种方法来查看它是否基于存在解决方案的存在而停止,该解决方案解决了寻找 catch 是否附加到 p 的问题 -所以这个问题至少和the halting problem一样难.

关于javascript - 检测 Angular JavaScript promise 链中是否存在下一个处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25294023/

相关文章:

javascript - 为什么我的 JavaScript 代码只在第二次点击时执行?

javascript - 对输入的每个字符做出不需要的提交

javascript - 索引页面与 AngularJS 应用程序的其余部分分开?

javascript - 在 Promise 的 then 中返回语句

javascript bluebird Promise -> 从异步列表中获取第一个文件

JavaScript 点击和拖动功能

javascript - 在 ES6 中导出常量的正确方法是什么?

javascript - 我什么时候应该在我的 Angular JS 单元测试中使用 $provide 与 Jasmine Spies

angularjs - 当 Controller 设置为 ng-repeat 时,我失去了对表单 Controller 的定义

javascript - 完成 Promise 链