正确使用promise await和async函数

时间:2018-06-11 06:16:20

标签: javascript promise async-await es6-promise bcrypt

router.post("/register", function (req, res) {

    console.log(req.body);

    // generate a salt
    (async function(){


    const salt = await bcrypt.genSalt(10);

    // hash the password along with our new salt
    const hash = await bcrypt.hash(req.body.txtPassword1, salt);
    return hash;
    })().then((data)=>{
        var txtPassword = data;
        let newUser = new userModel({
            userName: req.body.txtUserName,
            email: req.body.txtEmail,
            profilePic: req.body.txtFileUpload,
            password: txtPassword,
            isAdmin: false

        });
        newUser.save((function (err) {
            if (err) {
                console.log("failed to save the new User ! : ", err);

            } else {
                console.log("New user has been added successfully with Id", newUser._id);
            }
        }))

        req.flash('success', 'Registeration Successful');

        console.log("Session value ", req.session);
        console.log("value of txt password => ", txtPassword)
        res.render("blogHome", { title: "Blogs || Home" });
    });


}); 

我想知道这是否是使用await的正确方法。 我不得不采用这种方式,因为我只是尝试使用

var hash = await bcrypt.hash(req.body.txtPassword1,salt);

当我使用上面的代码时,我得到了意外的标识符错误,当我用Google搜索时,我发现了这一点 await必须在异步函数中使用,所以我将整个东西包装在IIFE中并使用.then()使用正常的promise处理 但我在不知不觉中觉得我复杂化了一件简单的事情。 任何人都可以指出最简单的方法来做到这一点。 我被迫使用promise的原因是因为异步执行 数据库保存语句总是在计算哈希值之前执行,这意味着密码为空,进而触发密码字段的模式验证

2 个答案:

答案 0 :(得分:1)

将函数传递给router.post async会更简单。您还可以考虑在通知注册成功之前等待保存新用户:

router.post("/register", async (req, res) => {
  const salt = await bcrypt.genSalt(10);
  // hash the password along with our new salt
  const txtPassword = await bcrypt.hash(req.body.txtPassword1, salt);

  const newUser = new userModel({
    userName: req.body.txtUserName,
    email: req.body.txtEmail,
    profilePic: req.body.txtFileUpload,
    password: txtPassword,
    isAdmin: false
  });

  newUser.save((err) => {
    if (err) return console.log("failed to save the new User ! : ", err);
    console.log("New user has been added successfully with Id", newUser._id);
    req.flash('success', 'Registeration Successful');
    console.log("Session value ", req.session);
    console.log("value of txt password => ", txtPassword)
    res.render("blogHome", {
      title: "Blogs || Home"
    });
  });
};

答案 1 :(得分:1)

这是正确的,除了你没有处理错误,你需要做 - 否则,现在,你在控制台中得到一个“未处理的拒绝”错误,并且从一些即将推出的Node.js版本开始,它' ll在未处理的拒绝中终止该过程。

  

但我在不知不觉中觉得我弄得很复杂。

:-)那是因为你正在处理一些基于承诺的事情和一些旧式的基于Node回调的事情。但是你可以通过宣传旧式的回调来使它更清晰。

假设您更新了newUserModel.save,因此它返回了一个promise而不是Node-style回调。然后:

router.post("/register", function (req, res) {
    // generate a salt
    (async function(){
        const salt = await bcrypt.genSalt(10);

        // hash the password along with our new salt
        const txtPassword = await bcrypt.hash(req.body.txtPassword1, salt);
        let newUser = new userModel({
            userName: req.body.txtUserName,
            email: req.body.txtEmail,
            profilePic: req.body.txtFileUpload,
            password: txtPassword,
            isAdmin: false

        });
        await newUser.save(); // *** Assumes a new promise-enabled `save`
        console.log("New user has been added successfully with Id", newUser._id);

        req.flash('success', 'Registeration Successful');

        console.log("Session value ", req.session);
        console.log("value of txt password => ", txtPassword)
        res.render("blogHome", { title: "Blogs || Home" });
    })().catch(err => {
        // handle error
    });
});

如果这是Express,您可能还会看Koa(来自同一个人),这样您就可以制作整个post回调async并同时正确处理错误(用中间件)。