在处理来自 AngularJS 承诺的错误时,使用 `.catch(function(error)` 和 `function(err Response)` 有啥区别? [重复]

Posted

技术标签:

【中文标题】在处理来自 AngularJS 承诺的错误时,使用 `.catch(function(error)` 和 `function(err Response)` 有啥区别? [重复]【英文标题】:What's the difference between using `.catch(function(error)` and `function(errResponse)` when handing errors from AngularJS promises? [duplicate]在处理来自 AngularJS 承诺的错误时,使用 `.catch(function(error)` 和 `function(err Response)` 有什么区别? [重复] 【发布时间】:2017-08-26 10:50:52 【问题描述】:

我正在阅读 AngularJS Up and Running。在第 6 章中,它提到了如何处理来自 Promise 的错误:

$http.get('/api/server-config').then(function(configResponse) 
    return $http.get('/api/' + configResponse.data.USER_END_POINT);
).then(function(userResponse) 
    return $http.get('/api/' + userResponse.data.id + '/items');
).then(function(itemResponse) 
    // Display items here
, function(error) 
    // Common error handling
);

在其他地方,我看到 .catch() 被使用(例如,这里的答案:Assigning variable from a factory to a control doesn't work 使用 .catch() 就像这样:

BaseService.fetch.stuffs
.then(function(data) 
    self.stuffies = data;
    console.log(self.stuffies);
).catch(function(errorResponse) 
    self.cerrorMessages = errorResponse.data;
);

我的问题是,上面的方法和书中介绍的方法有什么区别:

BaseService.fetch.stuffs
.then(function(data) 
    self.stuffies = data;
    console.log(self.stuffies);
, function(error) 
    self.cerrorMessages = errorResponse.data;
);

什么是首选?

【问题讨论】:

【参考方案1】:

区别:

如果服务 api 出现错误,function(error) 将捕获它。

但是如果你的成功方法function(data) 抛出一些错误,那么只有.catch() 可以捕获它。

例子:

promise().then(function (data) 
  throw new Error('execption from success');
).catch(function (err) 
  // execption from success caught!!
);

promise().then(function (data) 
  throw new Error('execption from success');
, function (error) 
  // execption from success : NOT caught
);

Read more

首选:

promise().then(function (data) 
 // handle data
, function (error) 
  // handle error from api
).catch(function (err) 
  // handle error from response.
);

【讨论】:

【参考方案2】:

根据AngularJS 1.2 documentation

catch(errorCallback)promise.then(null, errorCallback) 的简写

这意味着您可以互换使用这两种语法。

【讨论】:

这不是 OP 要求的。它基本上是 1 then vs 2 thens。这个问题肯定是一个骗局,因为它被多次讨论过。【参考方案3】:

catch 语法更好,因为它将错误处理分离到自己的单一通道,远离控制流,它被认为是良好的实践,由 bluebird.js 和其他人推广,而使用 错误处理函数 作为 then 函数的第二个参数可以被认为是一种反模式。

你可以找到一些关于它们的非常好的读物:

http://www.datchley.name/promise-patterns-anti-patterns/

http://taoofcode.net/promise-anti-patterns/

https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns

可以通过一个例子来说明两者之间的区别。至于您发布的第一段代码:

$http.get('/api/server-config').then(function(configResponse) 
    // create another promising chain here
    $http.get("/something-else").then(function(response) 
       // Do something
    ); 
    return $http.get('/api/' + configResponse.data.USER_END_POINT);
).then(function(userResponse) 
    return $http.get('/api/' + userResponse.data.id + '/items');
).then(function(itemResponse) 
    // Display items here
, function(error) 
    // Common error handling
);

如果我不只是返回 Promise,而是在第一个 Promise 解析器中调用另一个异步函数,则该函数的错误将永远不会到达最后一个错误处理程序,如果我忘记单独处理该新函数的错误,它将被吞下去。

不过,这个问题可以使用 catch 来解决:

$http.get('/api/server-config').then(function(configResponse) 
    // create another promising chain here
    $http.get("/something-else").then(function(response) 
       // Do something
    ); 
    return $http.get('/api/' + configResponse.data.USER_END_POINT);
).then(function(userResponse) 
    return $http.get('/api/' + userResponse.data.id + '/items');
).then(function(itemResponse) 
    // Display items here
).catch(function(error) 
    // error from nested function something else, can also be handled here 
    // within a single error handling channel
);

【讨论】:

你确定它是这样工作的吗?你试过吗?我看不出嵌套函数的错误是如何冒泡到处理程序的。实际上,我认为您的两个示例是相同的,只是使用的语法略有不同。

以上是关于在处理来自 AngularJS 承诺的错误时,使用 `.catch(function(error)` 和 `function(err Response)` 有啥区别? [重复]的主要内容,如果未能解决你的问题,请参考以下文章

在哪里处理AngularJS后端错误

AngularJS 测试 - 来自服务的承诺无法解决

如何在angularjs中链接promise错误函数

未捕获(承诺):TypeError:无法读取未定义的属性“创建”(离子 3.9,Angularjs 5.0.3)

使用 fetch 和 ES6 承诺处理自定义错误的最简洁方法

Javascript 承诺在没有错误时捕获块启动