在不触发成功回调的情况下捕获 $q 服务中的拒绝
catch rejection in $q service without triggering success callbacks
我有一个 return 是 $q
(Q) 承诺的方法:
var subtypesMetadataResolved = restService.getNodeSubtypesMetadata();
现在,当元数据可用时,我想 运行 两个函数来处理它们。首先,我想像这样链接它们:
subtypesMetadataResolved.then(createNodes).then(prepareDataForWidgets)
但后来我意识到,因为它们都需要由 subtypesMetadataResolved
承诺 return 编辑的数据,所以我需要 return 这些数据也来自 createNodes
成功回调,以便它被传递到 prepareDataForWidgets
,这不是一个选项。然后我就这样做了:
subtypesMetadataResolved.then(createNodes)
subtypesMetadataResolved.then(prepareDataForWidgets)
这符合我的需要。但现在的问题是如何在 subtypesMetadataResolved
被拒绝时调用我的 rejection
回调,并且在这种情况下既不触发 createNodes
也不触发 prepareDataForWidgets
回调?我有以下内容,但在触发 nodeSubtypesMetadataErrorCb
之后它还会触发 createNodes
回调:
subtypesMetadataResolved.catch(nodeSubtypesMetadataErrorCb);
subtypesMetadataResolved.then(createNodes)
subtypesMetadataResolved.then(prepareDataForWidgets)
我是这样拒绝的subtypesMetadataResolved
:
编辑:
function getNodeSubtypesMetadata(subtype) {
return $q.when("success!").then(function(){
debugger
throw new Error();
});
}
var subtypesMetadataResolved = getNodeSubtypesMetadata();
subtypesMetadataResolved.then(successCb1);
subtypesMetadataResolved.then(successCb2);
subtypesMetadataResolved.catch(nodeSubtypesMetadataErrorCb);
$q.all([
typesMetadataResolved,
subtypesMetadataResolved
]).then(init);
问题是您将带有 handled 错误的承诺分配给 subtypesMetadataResolved
。如果您对此调用 .then()
,它 将 调用 then()
回调,因为 .catch()
回调本质上是 "handling" 错误。
要解决这个问题,请将 unhandled 承诺分配给您的变量,然后调用 .catch()
/.then()
:
var subtypesMetadataResolved = getNodeSubtypesMetadata();
subtypesMetadataResolved.catch(nodeSubtypesMetadataErrorCb);
subtypesMetadataResolved.then(function(){
debugger
});
subtypesMetadataResolved.then(function () {
debugger
});
作为风格问题,我建议将 catch
行放在 then
行之后,但这对代码的行为应该没有明显的影响。
查看这行代码:
getNodeSubtypesMetadata().catch(nodeSubtypesMetadataErrorCb)
有两个承诺。第一个是 getNodeSubtypesMetadata()
返回的承诺,它被拒绝了。第二个承诺由 catch(nodeSubtypesMetadataErrorCb)
返回,它已实现。因此,当您将上述表达式的结果分配给一个变量时,您将获得第二个已实现的承诺。由于您对第一个承诺感兴趣,因此需要将代码更改为:
var subtypesMetadataResolved = getNodeSubtypesMetadata();
subtypesMetadataResolved.catch(nodeSubtypesMetadataErrorCb);
subtypesMetadataResolved.then(function(){
debugger
});
subtypesMetadataResolved.then(function () {
debugger
});
编辑: 作为替代方案,要让两个函数都作用于同一个已实现的承诺,您可以只用一个函数包装它们:
function nodeSubtypesMetadataFulfilledCb(metadata) {
createNodes(metadata);
prepareDataForWidgets(metadata);
}
subtypesMetadataResolved.then(
nodeSubtypesMetadataFulfilledCb,
nodeSubtypesMetadataErrorCb);
我有一个 return 是 $q
(Q) 承诺的方法:
var subtypesMetadataResolved = restService.getNodeSubtypesMetadata();
现在,当元数据可用时,我想 运行 两个函数来处理它们。首先,我想像这样链接它们:
subtypesMetadataResolved.then(createNodes).then(prepareDataForWidgets)
但后来我意识到,因为它们都需要由 subtypesMetadataResolved
承诺 return 编辑的数据,所以我需要 return 这些数据也来自 createNodes
成功回调,以便它被传递到 prepareDataForWidgets
,这不是一个选项。然后我就这样做了:
subtypesMetadataResolved.then(createNodes)
subtypesMetadataResolved.then(prepareDataForWidgets)
这符合我的需要。但现在的问题是如何在 subtypesMetadataResolved
被拒绝时调用我的 rejection
回调,并且在这种情况下既不触发 createNodes
也不触发 prepareDataForWidgets
回调?我有以下内容,但在触发 nodeSubtypesMetadataErrorCb
之后它还会触发 createNodes
回调:
subtypesMetadataResolved.catch(nodeSubtypesMetadataErrorCb);
subtypesMetadataResolved.then(createNodes)
subtypesMetadataResolved.then(prepareDataForWidgets)
我是这样拒绝的subtypesMetadataResolved
:
编辑:
function getNodeSubtypesMetadata(subtype) {
return $q.when("success!").then(function(){
debugger
throw new Error();
});
}
var subtypesMetadataResolved = getNodeSubtypesMetadata();
subtypesMetadataResolved.then(successCb1);
subtypesMetadataResolved.then(successCb2);
subtypesMetadataResolved.catch(nodeSubtypesMetadataErrorCb);
$q.all([
typesMetadataResolved,
subtypesMetadataResolved
]).then(init);
问题是您将带有 handled 错误的承诺分配给 subtypesMetadataResolved
。如果您对此调用 .then()
,它 将 调用 then()
回调,因为 .catch()
回调本质上是 "handling" 错误。
要解决这个问题,请将 unhandled 承诺分配给您的变量,然后调用 .catch()
/.then()
:
var subtypesMetadataResolved = getNodeSubtypesMetadata();
subtypesMetadataResolved.catch(nodeSubtypesMetadataErrorCb);
subtypesMetadataResolved.then(function(){
debugger
});
subtypesMetadataResolved.then(function () {
debugger
});
作为风格问题,我建议将 catch
行放在 then
行之后,但这对代码的行为应该没有明显的影响。
查看这行代码:
getNodeSubtypesMetadata().catch(nodeSubtypesMetadataErrorCb)
有两个承诺。第一个是 getNodeSubtypesMetadata()
返回的承诺,它被拒绝了。第二个承诺由 catch(nodeSubtypesMetadataErrorCb)
返回,它已实现。因此,当您将上述表达式的结果分配给一个变量时,您将获得第二个已实现的承诺。由于您对第一个承诺感兴趣,因此需要将代码更改为:
var subtypesMetadataResolved = getNodeSubtypesMetadata();
subtypesMetadataResolved.catch(nodeSubtypesMetadataErrorCb);
subtypesMetadataResolved.then(function(){
debugger
});
subtypesMetadataResolved.then(function () {
debugger
});
编辑: 作为替代方案,要让两个函数都作用于同一个已实现的承诺,您可以只用一个函数包装它们:
function nodeSubtypesMetadataFulfilledCb(metadata) {
createNodes(metadata);
prepareDataForWidgets(metadata);
}
subtypesMetadataResolved.then(
nodeSubtypesMetadataFulfilledCb,
nodeSubtypesMetadataErrorCb);