首页 > 解决方案 > 中间件转换为异步/等待

问题描述

我开始学习 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");
}

};

标签: asynchronousecmascript-6async-awaitmiddleware

解决方案


当您像这里一样只有一个异步操作时,从切换到await. 当您需要对多个异步操作进行排序甚至可能有一些分支时,更大的好处就会出现。然后await让您编写更简单的代码。

另外,这里的大部分代码实际上只是检查结果并将正确的错误消息返回给用户,这并没有变得更简单,await因为它只是一堆死记硬背的检查。

这是一个实现,它也尝试使用异常来合并所有错误返回,这样你就没有那么多地方在做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");
    });
};

请注意,在这两种情况下,我都会确保并记录一个实际的数据库错误(如果有的话)。


推荐阅读