中间件转换为 async/await
Middleware transform to async/await
我开始学习 ES6,并且正在将我的项目从 ES5 转换为 ES6。我想问一下在中间件中使用 async/await 是否有意义?如何在此示例中使用它:
middlewareObj.checkCampground = (req,res,next) =>{
if(req.isAuthenticated()){
Campground.findById(req.params.id, (err, foundCampground) =>{
if(err || !foundCampground){
req.flash("error", "Campground not found");
res.redirect("back");
} else {
if(foundCampground.author.id.equals(req.user._id) || req.user.isAdmin){
next();
} else {
req.flash("error", "You don't have permission to do that");
res.redirect("back");
}
}
});
} else {
req.flash("error", "You need to be logged in to do that");
res.redirect("back");
}
};
当您像此处那样只有一个异步操作时,切换到 await
并不会获得太多(如果有的话)。当您需要对多个异步操作进行排序甚至可能有一些分支时,更大的好处就会出现。然后 await
可以让你编写更简单的代码。
此外,这里的大部分代码实际上只是关于检查结果并将正确的错误消息返回给用户,使用 await
并没有变得更简单,因为它只是一堆死记硬背检查任何一种方式。
这里有一个实现,它也尝试使用异常来合并所有错误 returns,这样您就不会在很多地方做 req.flash()
和 res.redirect()
:
middlewareObj.checkCampground = async (req,res,next) => {
try {
if(req.isAuthenticated()) {
throw new Error("You need to be logged in to do that");
}
const foundCampground = await Campground.findById(req.params.id);
if (!foundCampground) {
throw new Error("Campgound not found")
}
if (foundCampground.author.id.equals(req.user._id) || req.user.isAdmin) {
next();
} else {
throw new Error("You don't have permission to do that");
}
} catch(e) {
console.log(e);
req.flash(e.message);
res.redirect("back");
}
};
这是另一种没有 async/await
的替代方法,它只是试图稍微整合错误处理。您无法回避这样一个事实,即存在三个 if
检查和四个可能的错误:
middlewareObj.checkCampground = (req,res,next) => {
function error(msg, location = "back") {
req.flash(msg);
res.redirect(location);
}
if(req.isAuthenticated()) {
error("You need to be logged in to do that");
return;
}
Campground.findById(req.params.id).then(foundCampground => {
if (!foundCampground) {
error("Campground not found");
} else if (foundCampground.author.id.equals(req.user._id) || req.user.isAdmin) {
next();
} else {
error("You don't have permission to do that");
}
}).catch(err => {
console.log(err);
error("Database Error - Campground not found");
});
};
请注意,在这两种情况下,我都会确保并记录实际的数据库错误(如果有的话)。
我开始学习 ES6,并且正在将我的项目从 ES5 转换为 ES6。我想问一下在中间件中使用 async/await 是否有意义?如何在此示例中使用它:
middlewareObj.checkCampground = (req,res,next) =>{
if(req.isAuthenticated()){
Campground.findById(req.params.id, (err, foundCampground) =>{
if(err || !foundCampground){
req.flash("error", "Campground not found");
res.redirect("back");
} else {
if(foundCampground.author.id.equals(req.user._id) || req.user.isAdmin){
next();
} else {
req.flash("error", "You don't have permission to do that");
res.redirect("back");
}
}
});
} else {
req.flash("error", "You need to be logged in to do that");
res.redirect("back");
}
};
当您像此处那样只有一个异步操作时,切换到 await
并不会获得太多(如果有的话)。当您需要对多个异步操作进行排序甚至可能有一些分支时,更大的好处就会出现。然后 await
可以让你编写更简单的代码。
此外,这里的大部分代码实际上只是关于检查结果并将正确的错误消息返回给用户,使用 await
并没有变得更简单,因为它只是一堆死记硬背检查任何一种方式。
这里有一个实现,它也尝试使用异常来合并所有错误 returns,这样您就不会在很多地方做 req.flash()
和 res.redirect()
:
middlewareObj.checkCampground = async (req,res,next) => {
try {
if(req.isAuthenticated()) {
throw new Error("You need to be logged in to do that");
}
const foundCampground = await Campground.findById(req.params.id);
if (!foundCampground) {
throw new Error("Campgound not found")
}
if (foundCampground.author.id.equals(req.user._id) || req.user.isAdmin) {
next();
} else {
throw new Error("You don't have permission to do that");
}
} catch(e) {
console.log(e);
req.flash(e.message);
res.redirect("back");
}
};
这是另一种没有 async/await
的替代方法,它只是试图稍微整合错误处理。您无法回避这样一个事实,即存在三个 if
检查和四个可能的错误:
middlewareObj.checkCampground = (req,res,next) => {
function error(msg, location = "back") {
req.flash(msg);
res.redirect(location);
}
if(req.isAuthenticated()) {
error("You need to be logged in to do that");
return;
}
Campground.findById(req.params.id).then(foundCampground => {
if (!foundCampground) {
error("Campground not found");
} else if (foundCampground.author.id.equals(req.user._id) || req.user.isAdmin) {
next();
} else {
error("You don't have permission to do that");
}
}).catch(err => {
console.log(err);
error("Database Error - Campground not found");
});
};
请注意,在这两种情况下,我都会确保并记录实际的数据库错误(如果有的话)。