iRo*_*tia 1 javascript mongoose node.js promise
我上一篇文章中强调的某些性能建议我参考stackoverflow 中的以下问题避免显式的 Promise 构造反模式
坦白说,我对 JS 和 Node 都是新手,也没有经常使用 Promise。我去读了那些文章,但要么我无法理解或无法联系,要么我对承诺的理解一直模糊/错误
所以我决定在新线程中提出这个问题并寻求帮助。
我正在创建帮助程序/通用函数,我可以用它来保持代码整洁,如果我想随时更改函数内部的任何内容,我不必手动更改每个函数。
这些是我制作的功能
//Find user by email Address
const findUserByEmail = (emailAddress) => {
return new Promise((resolve, reject) => {
User.findOne({email: emailAddress}).then(response => {
resolve(res)
}).catch(error => {
reject("Error in findUserByEmail", error);
})
})
}
//Create User
const createNewUser = (newUserDetails) => {
return new Promise((resolve, reject) => {
new User({
fullName: newUserDetails.fullName,
email: newUserDetails.email,
image: newUserDetails.image,
gender: newUserDetails.gender,
age: newUserDetails.age
}).save().then((response) => {
resolve(response)
}).catch((error) => {
reject("Problem in Creating New User", error)
})
})
}
Run Code Online (Sandbox Code Playgroud)
现在,我假设 certainPerformance 说的是过度使用承诺,因为 return new Promise((resolve, reject) => {当我已经在 mongoose 中使用承诺时,我正在创建新的承诺User.findOne({email: emailAddress}).then(response => {?
但我创建这些承诺的原因是,当我在导入后从应用程序中的任何位置调用这些辅助函数时
const { findUserByEmail } = require("./my_db_query");
Run Code Online (Sandbox Code Playgroud)
我可能希望它返回响应或在出现错误时抛出错误
findUserByEmail("test@example.com").then(/*...*/).catch(/*...*/);
Run Code Online (Sandbox Code Playgroud)
如果我更改上面的代码片段而不添加新的承诺
function findUserByEmail (email) {
return User.findOne({email: email}).then(currentUser => currentUser).catch(error => error)
}
Run Code Online (Sandbox Code Playgroud)
那我可能就不能.then进去.catch了findUserByEmail("test@example.com")?
在应用程序的 API 路径中,我将调用该findUserByEmail("test@example.com")函数,如果出现错误,我会想做其他事情(对于不同的情况,这会有所不同,因此我不能在我的辅助函数中使用它)。
return new Promise((resolve, reject) => {现在做而不是只做一件 有意义吗return User.findOne(?还是我错过了什么?
因为.findOne已经返回了 a Promise,所以不需要用 - 构造一个新的new Promise- 相反,只需根据需要用和链接到现有Promise链上即可。这样的链可以有任意数量的s 和s - 仅仅因为您使用 1并不能阻止您在其他地方使用相同的解析值。为了显示:.then.catchPromise.then.catchPromise.then
makePromise()
.then((result) => {
console.log(result);
// Returning inside a `.then` will pass along the value to the next `.then`:
return result;
})
.then((result) => {
// this `result` will be the same as the one above
});
Run Code Online (Sandbox Code Playgroud)
换句话说 - 无需new Promise每次您希望能够使用另一个 时都构造 a .then。所以:
那么我可能无法在 findUserByEmail("test@example.com") 中进行 .then 和 .catch
.then不正确 - 你确实可以用任意数量的s 和es链接到现有 Promise 的末尾.catch。
请注意,.then仅返回其参数而不执行任何其他操作(例如.then(currentUser => currentUser))是多余的 - 它根本不会执行任何操作。另请注意, a.catch将捕获Promise 拒绝并解析为已解决 Promise。所以如果你这样做
function findUserByEmail(email) {
return User.findOne({email: email})
.then(currentUser => currentUser)
.catch(error => error)
}
Run Code Online (Sandbox Code Playgroud)
这catch意味着 的调用者findUserByEmail将无法出错catch,因为任何可能的错误都被捕获在findUserByEmails中catch。通常,允许错误渗透到函数的调用者是一个好主意,这样您就可以,例如:
someFunctionThatReturnsPromise('foobar')
.then((result) => {
// everything is normal, send the result
res.send(result);
})
.catch((err) => {
// there was an error, set response status code to 500:
res.status(500).send('there was an error');
})
Run Code Online (Sandbox Code Playgroud)
因此,除非您的函数findUserByEmail或createNewUser辅助函数在出现错误时需要执行特定的操作,否则最好只返回Promise单独的内容:
const findUserByEmail = email => User.findOne(email);
const createNewUser = newUserDetails => new User(newUserDetails).save();
Run Code Online (Sandbox Code Playgroud)
如果您的辅助函数确实需要在出现错误时执行某些操作,那么为了确保错误正确传递给函数的调用者,我建议将错误抛出catch:
const findUserByEmail = email => User.findOne(email)
.catch((err) => {
// error handling - save error text somewhere, do a console.log, etc
throw err;
});
Run Code Online (Sandbox Code Playgroud)
这样您就可以catch在有其他事情需要时findUserByEmail。否则,如果你做类似的事情
const findUserByEmail = email => User.findOne(email)
.catch((err) => {
// do something with err
return err;
});
Run Code Online (Sandbox Code Playgroud)
那么调用者findUserByEmail必须检查结果.then是否确实是一个错误,这很奇怪:
findUserByEmail('foo@bar.com')
.then((result) => {
if (result instanceof Error) {
// do something
} else {
// No errors
}
});
Run Code Online (Sandbox Code Playgroud)
最好将错误抛出findUserByEmail's catch,这样 's 的消费者也findUserByEmail可以。 .catch
| 归档时间: |
|
| 查看次数: |
725 次 |
| 最近记录: |