Gro*_*cho 66 javascript angularjs karma-runner angular-promise angularjs-1.6
我们在Angular应用程序中有一个解决承诺的模式,直到Angular 1.6.0为止我们一直很好:
resource.get().$promise
.then(function (response) {
// do something with the response
}, function (error) {
// pass the error the the error service
return errorService.handleError(error);
});
Run Code Online (Sandbox Code Playgroud)
以下是我们如何在Karma中触发错误:
resourceMock.get = function () {
var deferred = $q.defer();
deferred.reject(error);
return { $promise: deferred.promise };
};
Run Code Online (Sandbox Code Playgroud)
现在,随着1.6.0的更新,Angular突然抱怨我们的单元测试(在Karma中)因"可能未处理的拒绝"错误而被拒绝的承诺.但是我们正在处理调用错误服务的第二个函数中的拒绝.
Angular究竟在寻找什么?它是如何让我们"处理"拒绝的?
Cen*_*ael 65
尝试将此代码添加到您的配置中.我有一次类似的问题,这个解决方法就是这个伎俩.
app.config(['$qProvider', function ($qProvider) {
$qProvider.errorOnUnhandledRejections(false);
}]);
Run Code Online (Sandbox Code Playgroud)
Lou*_*uis 22
您显示的代码将处理在调用之前发生的拒绝.then.在这种情况下,将调用您传递给的第二个回调.then,并将处理拒绝.
但是,当您呼叫的承诺.then成功时,它会调用第一个回调.如果此回调引发异常或返回被拒绝的承诺,则不会处理此结果拒绝,因为第二个回调不会处理第一个引起的拒绝.这就是承诺实现符合Promises/A +规范的工作方式,以及Angular承诺是否合规.
您可以使用以下代码说明这一点:
function handle(p) {
p.then(
() => {
// This is never caught.
throw new Error("bar");
},
(err) => {
console.log("rejected with", err);
});
}
handle(Promise.resolve(1));
// We do catch this rejection.
handle(Promise.reject(new Error("foo")));
Run Code Online (Sandbox Code Playgroud)
如果你在Node中运行它,它也符合Promises/A +,你得到:
rejected with Error: foo
at Object.<anonymous> (/tmp/t10/test.js:12:23)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:394:7)
at startup (bootstrap_node.js:149:9)
at bootstrap_node.js:509:3
(node:17426) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: bar
Run Code Online (Sandbox Code Playgroud)
Gro*_*cho 18
通过回滚到Angular 1.5.9并重新运行测试找到了问题.这是一个简单的注入问题,但Angular 1.6.0通过抛出"可能未处理的拒绝"错误取代了这一点,混淆了实际的错误.
And*_*kyi 16
第一个选项只是通过errorOnUnhandledRejections按照建议配置$ qProvider配置来隐藏错误并禁用它Cengkuru Michael
但这样只会关闭日志记录.错误本身将保留
在这种情况下,更好的解决方案是 - 使用.catch(fn)方法处理拒绝:
resource.get().$promise
.then(function (response) {})
.catch(function (err) {});
Run Code Online (Sandbox Code Playgroud)
链接:
小智 5
您可以通过关闭 errorOnUnhandledRejections 来掩盖问题,但错误表明您需要“处理可能的拒绝”,因此您只需要在承诺中添加一个捕获。
resource.get().$promise
.then(function (response) {
// do something with the response
}).catch(function (error)) {
// pass the error to the error service
return errorService.handleError(error);
});
Run Code Online (Sandbox Code Playgroud)
参考:https : //github.com/angular-ui/ui-router/issues/2889
为了避免键入其他.catch(function () {})在多个地方的代码,您可以添加decorator到$exceptionHandler。
这是一个比其他选项更为冗长的选项,但您只需要在一个地方进行更改即可。
angular
.module('app')
.config(configDecorators);
configDecorators.$inject = ["$provide"];
function configDecorators($provide) {
$provide.decorator("$exceptionHandler", exceptionHandler);
exceptionHandler.$inject = ['$delegate', '$injector'];
function exceptionHandler($delegate, $injector) {
return function (exception, cause) {
if ((exception.toString().toLowerCase()).includes("Possibly unhandled rejection".toLowerCase())) {
console.log(exception); /* optional to log the "Possibly unhandled rejection" */
return;
}
$delegate(exception, cause);
};
}
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
93240 次 |
| 最近记录: |