Node.js 节点承诺控制流

Node.js 节点承诺控制流,node.js,promise,Node.js,Promise,我使用bluebird中的promise发送mysql查询并管理控制流和错误。下面是它的外观: sendQuery1(..) .then(sendQuery2(..)) .then(function(results from last query){ if(rain){ res.render(...) }else{ /* I need to send additional 2 queries here */

我使用bluebird中的promise发送mysql查询并管理控制流和错误。下面是它的外观:

sendQuery1(..)
.then(sendQuery2(..))
.then(function(results from last query){
    if(rain){
        res.render(...)
    }else{
        /*
          I need to send additional 2 queries here
        */
    }
}).catch(errors);
承诺链非常方便,但是我发现如果里面有多个子链,那么错误处理会很混乱

在这里,我可能需要在/**/

return sendQuery3(..)
       .then(sendQuery4(..))
       .then(function(..){
            res.render(".....")
       }).catch(error2);

有没有更好的方法来处理这类问题?

我在这里没有看到您的问题。当您在一个链中有一个链时(您通常不会这样做,您应该在那里检查您的体系结构),您只需捕获错误,如图所示

我建议您使用全局(或本地)错误处理函数,并将其传递给catch函数。因此,即使有多个捕获,也可以使用相同的错误处理程序


在我看来,最好的解决方案是创建一个“承诺链旁路”,因此根据您的情况使用catch跳过某些部分。如果这不是您想要的,请说明您的问题。

我在这里没有看到您的问题。当您在一个链中有一个链时(您通常不会这样做,您应该在那里检查您的体系结构),您只需捕获错误,如图所示

我建议您使用全局(或本地)错误处理函数,并将其传递给catch函数。因此,即使有多个捕获,也可以使用相同的错误处理程序


在我看来,最好的解决方案是创建一个“承诺链旁路”,因此根据您的情况使用catch跳过某些部分。如果这不是您要查找的,请指定您的问题。

您将捕获错误,代码中没有问题。是的,它会变得混乱,但您可以使用以下方法保持代码干净,并仍然实现您的逻辑:

sendQuery1(..)
.then(sendQuery2(..))
.then(function(results from last query){
    if(rain){
        res.render(...)
        throw new Error('breakChain');  //intentionally throwing error to skip the remaining chain
    }
    return; //will act like 'else'
})
.then(sendQuery3(..))
.then(sendQuery4(..))
.catch(function (e) {
    if(e.message != 'breakChain')   //act on error if it was other than 'breakChain'
        throw e;
});

您将捕获错误,代码中没有问题。是的,它会变得混乱,但您可以使用以下方法保持代码干净,并仍然实现您的逻辑:

sendQuery1(..)
.then(sendQuery2(..))
.then(function(results from last query){
    if(rain){
        res.render(...)
        throw new Error('breakChain');  //intentionally throwing error to skip the remaining chain
    }
    return; //will act like 'else'
})
.then(sendQuery3(..))
.then(sendQuery4(..))
.catch(function (e) {
    if(e.message != 'breakChain')   //act on error if it was other than 'breakChain'
        throw e;
});

你们在这里讨论的是基于某种逻辑条件的链的分支。通常,最好是实际分支链,而不是抛出一个错误来中止链的其余部分。这使错误保持为错误,而不是Shaharyar提出的合成一个不是真正错误的错误的方案

您可以通过从
处理程序中返回新的承诺链来分支该链。然后()
处理程序如下:

sendQuery1(..).then(function(r1) {
    return sendQuery2(...);
}).then(function(r2){
    if (rain){
        // processing is done, so just render
        res.render(...)
    } else {
        // return promise here to attach this new branch to the original chain
        return sendQuery3(..).then(sendQuery4).then(function() {
            // process last query
        });
    }
}).catch(errors);

仅供参考,由于您只发布了伪代码,而不是真实代码,并且我们无法看到哪些函数需要访问哪些先前的结果才能完成其工作,因此我们无法完全优化代码。这是一个在承诺链中如何进行分支的示例。这就是你可能想要使用的原则。如果您展示真实的代码,我们可以提供更具体、更优化的答案。

您在这里讨论的是基于某些逻辑条件的链分支。通常,最好是实际分支链,而不是抛出一个错误来中止链的其余部分。这使错误保持为错误,而不是Shaharyar提出的合成一个不是真正错误的错误的方案

您可以通过从
处理程序中返回新的承诺链来分支该链。然后()
处理程序如下:

sendQuery1(..).then(function(r1) {
    return sendQuery2(...);
}).then(function(r2){
    if (rain){
        // processing is done, so just render
        res.render(...)
    } else {
        // return promise here to attach this new branch to the original chain
        return sendQuery3(..).then(sendQuery4).then(function() {
            // process last query
        });
    }
}).catch(errors);


仅供参考,由于您只发布了伪代码,而不是真实代码,并且我们无法看到哪些函数需要访问哪些先前的结果才能完成其工作,因此我们无法完全优化代码。这是一个在承诺链中如何进行分支的示例。这就是你可能想要使用的原则。如果您展示您的真实代码,我们可以提供更具体和优化的答案。

您使用的是哪个
nodejs
版本?问题的具体原因是什么?错误处理将如何变得混乱?您使用的是哪个
nodejs
版本?问题的具体原因是什么?错误处理将如何变得混乱?嗨,NikxDa,感谢您的快速响应。你能提供更多关于“承诺链旁路”的细节吗?我知道全局错误处理程序可以工作,但我仍然需要将错误捕获附加到每个承诺链,包括每个链中的子链,这就是我正在努力解决的问题。通过故意抛出一个错误来绕过,就像Shaharyar的回答一样。然后你可以跳过其他“then”部分,直接跳到catch,从那里你可以继续。这样,您就不需要嵌套条件。非常感谢。对不起,我不能选择两个正确的答案!圣诞快乐!使用global是一个非常糟糕的建议。嗨,NikxDa,谢谢你的快速回复。你能提供更多关于“承诺链旁路”的细节吗?我知道全局错误处理程序可以工作,但我仍然需要将错误捕获附加到每个承诺链,包括每个链中的子链,这就是我正在努力解决的问题。通过故意抛出一个错误来绕过,就像Shaharyar的回答一样。然后你可以跳过其他“then”部分,直接跳到catch,从那里你可以继续。这样,您就不需要嵌套条件。非常感谢。对不起,我不能选择两个正确的答案!圣诞快乐!使用全局是一个非常糟糕的建议。@pano-在非错误条件下合成错误不是一个很好的设计模式,只是表明您需要分支链,而不是只有一个平面链。我提供了一个说明如何分支链的答案。仅供参考,这将不起作用:
sendQuery1(..)。然后(sendQuery2(..)
。在调用
sendQuery2(…)
之前,不会等到
sendQuery1(…)
完成,并且不允许在第二个查询中使用第一个查询的结果。我知道OP是这样显示的,但它不正确,不能正常工作。@jfriend00在这里引用您的话,它只是OP示例代码的伪a/c。他接受了答案,所以我想他知道如何使用b