在$q服务中捕获拒绝而不触发成功回调

catch rejection in $q service without triggering success callbacks

本文关键字:回调 成功 拒绝 服务      更新时间:2023-09-26

我有一个返回$q(Q)promise的方法:

var subtypesMetadataResolved = restService.getNodeSubtypesMetadata();

现在,当元数据可用时,我想运行两个函数来处理它们。首先,我想把它们像这样链起来:

subtypesMetadataResolved.then(createNodes).then(prepareDataForWidgets)

但后来我意识到,由于它们都需要subtypesMetadataResolved承诺返回的数据,我也需要从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);

问题是,您正在将带有已处理错误的promise分配给subtypesMetadataResolved。如果对此调用.then(),则调用then()回调,因为.catch()回调本质上是在"处理"错误。

要解决此问题,请将未处理的承诺分配给变量,然后在此调用.catch()/.then()

var subtypesMetadataResolved = getNodeSubtypesMetadata();
subtypesMetadataResolved.catch(nodeSubtypesMetadataErrorCb);
subtypesMetadataResolved.then(function(){
    debugger
});
subtypesMetadataResolved.then(function () {
    debugger
});

就风格而言,我建议将catch行放在then行之后,但这对代码的行为没有明显的影响。

查看这行代码:

getNodeSubtypesMetadata().catch(nodeSubtypesMetadataErrorCb)

有两个承诺。第一个是getNodeSubtypesMetadata()返回的promise,被拒绝。第二个承诺由catch(nodeSubtypesMetadataErrorCb)返回,并已实现。因此,当您将上述表达式的结果分配给一个变量时,您得到的是第二个已实现的promise。由于您有兴趣执行第一个承诺,您需要将代码更改为:

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);