我对诺言仍然还很陌生,目前正在使用蓝鸟,但是在我不确定如何最好地处理它的情况下。
因此,举例来说,我在Express应用程序中有一个Promise链,如下所示:
repository.Query(getAccountByIdQuery)
.catch(function(error){
res.status(404).send({ error: "No account found with this Id" });
})
.then(convertDocumentToModel)
.then(verifyOldPassword)
.catch(function(error) {
res.status(406).send({ OldPassword: error });
})
.then(changePassword)
.then(function(){
res.status(200).send();
})
.catch(function(error){
console.log(error);
res.status(500).send({ error: "Unable to change password" });
});
所以我的行为是:
因此,当前的捕获量似乎并没有停止链接,这是有道理的,因此,我想知道是否有办法让我根据错误将链接强制停止在某个点,或者是否有更好的方法进行结构化,以获得某种形式的分支行为,例如if X do Y else Z
。
任何帮助都会很棒。
此行为完全类似于同步抛出:
try{
throw new Error();
} catch(e){
// handle
}
// this code will run, since you recovered from the error!
这.catch
是能够从错误中恢复的一半。可能需要重新抛出信号以指示状态仍然是错误:
try{
throw new Error();
} catch(e){
// handle
throw e; // or a wrapper over e so we know it wasn't handled
}
// this code will not run
但是,仅此一种方法对您而言不起作用,因为以后的处理程序会捕获该错误。真正的问题是,广义的“ HANDLE
ANYTHING”错误处理程序通常是一种不好的做法,并且在其他编程语言和生态系统中却极度皱眉。因此,蓝鸟提供了类型化和谓语捕获。
附加的优点是您的业务逻辑根本不需要(也不应该)知道请求/响应周期。决定客户端获取哪种HTTP状态和错误不是查询的责任,而随着应用的增长,您可能希望将业务逻辑(如何查询数据库以及如何处理数据)与发送给客户端的内容分开(什么http状态代码,什么文本和什么响应)。
这是我编写您的代码的方式。
首先,我将.Query
抛出一个NoSuchAccountError
,将其从Promise.OperationalError
Bluebird已经提供的子类中继承出来。如果您不确定如何将错误归类,请告诉我。
我另外为其子类化AuthenticationError
,然后执行以下操作:
function changePassword(queryDataEtc){
return repository.Query(getAccountByIdQuery)
.then(convertDocumentToModel)
.then(verifyOldPassword)
.then(changePassword);
}
如您所见-它非常干净,您可以阅读文本,就像使用说明书一样,了解过程中发生的情况。它也与请求/响应分开。
现在,我将从路由处理程序中这样调用它:
changePassword(params)
.catch(NoSuchAccountError, function(e){
res.status(404).send({ error: "No account found with this Id" });
}).catch(AuthenticationError, function(e){
res.status(406).send({ OldPassword: error });
}).error(function(e){ // catches any remaining operational errors
res.status(500).send({ error: "Unable to change password" });
}).catch(function(e){
res.status(500).send({ error: "Unknown internal server error" });
});
这样,逻辑就全部集中在一个地方,而如何处理客户端错误的决定就都集中在一个地方,而且它们不会相互干扰。
问题内容: 我对诺言仍然相当陌生,并且目前正在使用蓝鸟,但是在我不确定如何最好地处理它的情况下。 因此,例如,我在快速应用程序中有一个promise链,如下所示: 所以我的行为是: 通过ID获取帐户 如果此时存在拒绝,请炸毁并返回错误 如果没有错误,则将文档转换为模型 使用数据库文档验证密码 如果密码不匹配,则炸开并返回其他错误 如果没有错误,请更改密码 然后返回成功 如果还有其他问题,请返回50
问题内容: 我正在做的事情涉及按顺序运行(进行一些设置,然后运行调用者感兴趣的实际命令),然后进行一些清理)。 就像是: 哪里是这样的: 在内部,我使用,它返回,并且有效地将事件的结果从返回给调用者。 现在,我还需要将事件从stdout和stderr发送到调用者,这些事件也来自EventEmitters。是否有一种方法可以使(Bluebird)Promises正常工作,或者它们只是妨碍发出多个事件
问题内容: 作为节点程序员。我习惯于使用“ nodebacks”来处理代码中的错误: 编写该函数时,我可以执行以下操作: 我如何用promises处理这种错误? 问题答案: 经验法则 每当您对如何使用Promise有所疑问时,请考虑一下同步版本。 至少对我来说,这比第一个参数有时是的回调要干净得多。 promises方式几乎总是与问题的同步版本非常相似: 使用回调函数时,myFn看起来像什么: 使
问题内容: 我有一个名为PaymentStrategy的服务,已注入我的控制器中。 paymentStrategy中的这种购买方法会触发几种需要顺序调用的方法。当buy()中的所有方法都完成后,需要调用then()。 这可能是微不足道的,但我对棱角还很陌生。 目前,在init()方法之后立即触发buy()。then()。我觉得我们需要将所有这些方法放在一个promise中,并应用$ q.all()
问题内容: 我必须做一个序列的承诺:我一次只有1个网址,这意味着只有1个诺言。每次我收到一个json时,其中一个都包含另一个json的网址,因此我必须做出另一个承诺。 我可以处理多个诺言,但是在这种情况下,我做不到,因为我没有所有的URL,只有一个。 这个例子不起作用,全部冻结。 问题答案: 您可以使用递归
问题内容: 使用诺言时,如何正确地退出取消按钮而不会引发错误?我的代码会发出带有所需复选框的警报确认。该代码按应对用户执行的方式执行,但会在控制台窗口中引发错误: 没抓住(承诺)取消 问题答案: 更新(2017年1月): 此问题已在v7中修复:v7升级指南↗ 您需要向Promise添加拒绝处理程序。另外,您可以使用一种快速的方法来简单地排除错误: PS。您使用的软件包称为SweetAlert 2