数据库操作套在回调函数中就出错

发布于 2022-09-06 09:12:50 字数 3210 浏览 14 评论 0

实现一个注册功能

user.post('/register', async(ctx) => {
    let {username, password, rePassword} = ctx.request.body;
    
    if (!username) {
        responseClient(ctx, 400, 2, '用户名不可为空');
        return;
    }
    if (!password) {
        responseClient(ctx, 400, 2, '密码不可为空');
        return;
    }
    if (password !== rePassword) {
        responseClient(ctx, 400, 2, '两次密码不一致');
        return;
    }   

    try{
       await User.findOne({username}, function(err, doc){
            if(err){
                 responseClient(ctx);
             }

             if(doc){
                 responseClient(ctx, 200, 1, '用户名已存在');
                 return;  
             }else{
                 //保存到数据库
                let user = new User({
                     username: username,
                     password: password,
                     type: 'user'
                 });

                 user.save(function(err, doc){
                     if(err){
                         console.log(err);
                     }
                     if(doc){
                         let data = {};
                         data.username = doc.username;
                         data.userType = doc.type;
                         data.userId = doc._id;
                         responseClient(ctx, 200, 0, '注册成功', data);
                         return;
                     }
                 });   
             }
         })

           }

    }catch(e){
        responseClient(ctx);
    }
})

当我这样写的时候有时候会注册成功有时候就会提示AssertionError [ERR_ASSERTION]: headers have already been sent

后来试了下这种写法就没问题

user.post('/register', async(ctx) => {
    let {username, password, rePassword} = ctx.request.body;
    
    if (!username) {
        responseClient(ctx, 400, 2, '用户名不可为空');
        return;
    }
    if (!password) {
        responseClient(ctx, 400, 2, '密码不可为空');
        return;
    }
    if (password !== rePassword) {
        responseClient(ctx, 400, 2, '两次密码不一致');
        return;
    }   

    try{
        let doc = await User.findOne({username})
        if(doc){
            responseClient(ctx, 200, 1, '用户名已存在');
            return
        }else{
            let user = new User({
                    username: username,
                    password: password,
                    type: 'user'
                });

            let newUser = await user.save();
            let data = {};
            data.username = newUser.username;
            data.userType = newUser.type;
            data.userId = newUser._id;
            responseClient(ctx, 200, 0, '注册成功', data);
            return;
        }

    }catch(e){
        responseClient(ctx);
    }
})

responseClient

    responseClient(ctx,httpCode = 500, code = 3,message='服务端异常',data={}) {
        let responseData = {};
        responseData.code = code;
        responseData.message = message;
        responseData.data = data;
        ctx.status = httpCode;
        ctx.body = responseData;
    }

请问第一种是我哪里写错了吗?正常的写法应该怎么写?

图片描述

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

秋意浓 2022-09-13 09:12:50

User.findOne()的内容能发一下吗?User.findOne()是不是返回Promise?你这样写试试:

user.post('/register', async(ctx) => {
let {username, password, rePassword} = ctx.request.body;

if (!username) {
    responseClient(ctx, 400, 2, '用户名不可为空');
    return;
}
if (!password) {
    responseClient(ctx, 400, 2, '密码不可为空');
    return;
}
if (password !== rePassword) {
    responseClient(ctx, 400, 2, '两次密码不一致');
    return;
}   

try{
   User.findOne({username}).then(function(doc,err){
        if(err){
             responseClient(ctx);
         }

         if(doc){
             responseClient(ctx, 200, 1, '用户名已存在');
             return;  
         }else{
             //保存到数据库
            let user = new User({
                 username: username,
                 password: password,
                 type: 'user'
             });

             user.save(function(err, doc){
                 if(err){
                     console.log(err);
                 }
                 if(doc){
                     let data = {};
                     data.username = doc.username;
                     data.userType = doc.type;
                     data.userId = doc._id;
                     responseClient(ctx, 200, 0, '注册成功', data);
                     return;
                 }
             });   
         }
     })

       }

}catch(e){
    responseClient(ctx);
}

})

轻拂→两袖风尘 2022-09-13 09:12:50

先说错在什么地方

if(err){
    responseClient(ctx);
    // 此处应该有return
}

err不为空时已经调用了responseClient,但是又继续往下走,这时doc显然是空,所以会走到else里面
,无论成功或是异常(我也不知道,因为看不到执行结果),最后都会再执行一次responseClient。2次调用向客户端响应的方法,就会出现:

headers have already been sent

第一种方式有点不知所云。callback和await/async本来是二选一,为什么第一种写法既有await又有callback?
至于正确的写法,只能说造成问题的主要是你没有return,后面的逻辑是否正确还要你自己执行看看。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文