Pet*_*erT 5 javascript node.js promise es6-promise
经过大量的谷歌搜索,我找不到一个明确的例子,如何避免编程每个捕获,以确定Promise拒绝错误是程序化还是可操作的.将此与提供回调的节点回调模式(error,params ...)进行比较,其中在error参数中干净地提供操作错误,并且通过throw链处理编程错误.
请告诉我,我正在犯一个noob错误,这是我错过的一个简单的答案.
EDIT Node v10.0.0现在通过添加错误代码解决了这个问题.
感谢RisingStack将此信息发送到我的收件箱:
https://blog.risingstack.com/node-js-10-lts-feature-breakdown
......而且正式而且简洁(一如既往):
https://nodejs.org/api/errors.html#errors_error_code
考虑一个常见的例子:
function logMeIn (email, password, login_token) {
selectFromDbByEmailAndCheckPwAndReturnId (email, password)
.then(id => { return updateUserIdLoginToken(id, login_token); })
.catch(error => {
// all rejects and throws end up here
console.log(error);
})
})
function selectFromDbByEmailAndCheckPwAndReturnId (email, password) {
return new Promise((resolve, reject) => {
db.sql.query( /* params */, (error, results) => {
blarg = 1; // <-- reference error, programmatic
// do your SELECT * FROM Users where email=? ... etc.
if (error) {
return reject(error); // <-- operational sql error
:
:
if (resultsRowsFromQuery.length === 0) {
// vvvvv operational error: user not found
return reject(new Error("User not in database"));
}
:
// hash password & salt, etc etc etc ...
:
return resolve(resultRowsFromQuery[0].id);
});
});
}
// no need to code out updateUserIdLoginToken...
Run Code Online (Sandbox Code Playgroud)
在这个示例中,catch将捕获程序错误和两个操作错误,并且我必须编程catch以确定哪个.如果我想向用户返回他们的电子邮件未找到的事实,我不能只使用该消息,因为我可能会意外地返回引用错误消息.(尴尬!)
但是,与sql.query模式进行比较,很明显错误是可操作的,因为blarg=1如果不在promise中,它会冒泡到更高的级别.
我看到关于拒绝值应该是什么以及如何区分的文档很少.我考虑过使用resolve(new Error()),以便我的成功实现功能确定是否存在操作错误,并且为程序错误保存.catch,但这只是愚蠢的.
那里有很多不好的信息,因为它在过去的7年中经常引用bluebird,Q,A +和ES6 ......很难找到ES6 Node/7/9的例子...... [我甚至看到了声称的链接使用.then(func A(),func B()).catch()将编程错误发送给B而不是catch().大声笑.]
思考?
编辑#1:无承诺请求示例:
function logMeIn (email, password, login_token) {
try {
selectFromDbByEmailAndCheckPwAndReturnId (email, password, (error, id) => {
if (error) {
console.log("Operational error:", error)
return;
}
// no error, got id, do next step...
updateUserIdLoginToken(id, login_token, error => {
// do next thing, like return res.render() or something...
});
});
} catch (e) {
console.error("Programmatic error:", e);
}
})
function selectFromDbByEmailAndCheckPwAndReturnId (email, password, callback) {
db.sql.query( /* params */, (error, results) => {
blarg = 1; // <-- reference error, programmatic
// do your SELECT * FROM Users where email=? ... etc.
if (error) {
return callback(error, null);
}
:
:
if (resultsRowsFromQuery.length === 0) {
// vvvvv operational error: user not found
return callback(new Error("User not in database"), null);
}
:
// hash password & salt, etc etc etc ...
:
return callback(null, id);
});
}
Run Code Online (Sandbox Code Playgroud)
您对节点样式和基于 Promise 的代码期望过高。这两种异步函数都区分操作错误和编程错误的概念,您实际上可以抛出/拒绝任何内容,这就是为什么您没有找到太多关于它的文档。这两种模式都是异步代码流的基元,仅此而已。节点样式版本有点尴尬,因为它允许传播同步和异步错误(您需要同时使用try-catch和if(error)来处理所有错误)。尽管他们应该只使用异步版本。在单个函数中使用两个“错误通道”并不是一个功能,它只是行为不当的代码。
节点样式或基于 Promise 的异步代码都不应该抛出常规同步错误。 因此,不要使用这两种不同的错误传播渠道来区分程序错误和操作错误。
那么要回答这个问题,你如何区分它们?就像处理常规同步代码一样,您必须引入自己的抽象:
OperationalError类,使用任意数量的子类,并使顶级代码区分OperationalError-s 和任何其他类型的错误。这就是我的推荐。| 归档时间: |
|
| 查看次数: |
105 次 |
| 最近记录: |