承诺是解决或拒绝,但我希望有一个失败选项:
users.parse(body)
.then(function (data){
if(data.status == 'fail') {
res.fail(data.data);
} else {
return users.saveUser(data.data);
}
}).then(function (user) {
res.success(merchant);
}).catch(function (err) {
res.error(err);
});
所以我基本上做的是使用名为'fail'的状态对象来解决它是否为失败进程,因此我发送失败消息而不是错误消息。
我做得对,无论如何上面的代码都会给我错误:
Unhandled rejection Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
答案 0 :(得分:1)
如果用户失败,您的第一个回调将返回undefined
,您的第二个then
回调仍会被执行,undefined
的值为user
。在res.success
之后调用res.fail
将导致异常,这将导致catch
回调被执行,因此它会尝试调用res.error
,这会再次引发标题错误已被发送。
您应该可以使用
解决此问题users.parse(body).then(function(data) {
if (data.status == 'fail') {
res.fail(data.data);
} else {
return users.saveUser(data.data).then(function(user) {
res.success(merchant);
});
}
}).catch(function(err) {
res.error(err);
});
然而,更清晰的解决方案是使用
users.parse(body).then(function(data) {
if (data.status == 'fail') return data;
else return users.saveUser(data.data);
}).then(function(user) {
if (data.status == 'fail')
res.fail(data.data);
else
res.success(merchant);
}, function(err) {
res.error(err);
});
使用Maybe
仿函数进行抽象可能会有所收获。
答案 1 :(得分:0)
你是对的,如果你需要“第三个结果”,你必须手动完成。您遇到的异常是由于res.success(...)
代码仍然在“失败”情况下执行,因为没有错误可以阻止它。
做承诺时的一个好的经验法则是实现任何通常应该中断“当时”流程作为拒绝的条件。这意味着只要users.parse
拒绝输入错误,您的代码就会变成更自然的版本,所有错误都会在一个地方处理:
users.parse(body).then(function(data) {
return users.saveUser(data.data);
}).then(function (user) {
res.success(merchant);
}).catch(function(err) {
if (err == 'fail') {
res.fail(data.data)
} else {
res.error(err);
}
});
如果您决定要在“成功”分支上处理解析失败,Bergi提供的解决方案也可以正常工作。