简体   繁体   English

承诺 {<pending> } 的 bcrypt 内部承诺

[英]Promise {<pending>} of bcrypt inside promise

I have a lambda function that is connected to Mongo via mongoose.我有一个通过 mongoose 连接到 Mongo 的 lambda 函数。 The user inputs a name and password on the frontend and the lambda function searches whether the user exists and afterwards the crypted password is compared via bcrypt.用户在前端输入名称和密码,lambda 函数搜索用户是否存在,然后通过 bcrypt 比较加密后的密码。

Right now bcrypt gives me {<promise pending>} , when I console.log(match).现在,当我 console.log(match) 时,bcrypt 给了我{<promise pending>}

However, I can't simply add an await as the check is inside a promise.但是,我不能简单地添加等待,因为检查在承诺中。

require("dotenv").config();
const mongoose = require("mongoose");
const User = require('../server/models/user');
const bcrypt = require('bcryptjs')

exports.handler = async (event, context) => {
  context.callbackWaitsForEmptyEventLoop = false;
  
  mongoose.connect(`${process.env.MONGO_URI}`,{
    useNewUrlParser: true,
    useUnifiedTopology: true,
  }
  );
  
  let {name, password} = JSON.parse(event.body);

 let fd = await new Promise((res,rej)=>User.findOne(
    {
      name:name,
    },
    (err, user) => {
      if (err) {
        rej({
          statusCode: 500,
          body: JSON.stringify({ msg: err.message }),
        });
      } else {
    //==>    const match = await bcrypt.compare(password, JSON.stringify(user.password)); 

 
        if (match) {
        let statusCode = user && match? 200:405
        res({
          statusCode,
          headers: {
            "Access-Control-Allow-Origin": "*", 
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ user}),
        });
      }
      }
    }
  ));
  return fd
};

So basically how can I 'await' bcrypt in that case or how could I write this function in another way?所以基本上我怎么能'等待' bcrypt 在这种情况下或者我怎么能以另一种方式编写这个函数? Thanks for reading!谢谢阅读!

You cannot use await there, because the callback in which it occurs is not an async function.您不能在那里使用await ,因为它发生的回调不是async函数。

However, you should better use the promise you can get from findOne :但是,您应该更好地使用可以从findOne获得的承诺:

exports.handler = async (event, context) => {
  context.callbackWaitsForEmptyEventLoop = false;
  
  mongoose.connect(process.env.MONGO_URI, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  });
  
  const {name, password} = JSON.parse(event.body);
  const user = await User.findOne({name}).exec();
  const match = user && await bcrypt.compare(password, user.password.toString()); 
  if (!match) {
    throw {
      statusCode: 405,
      body: "Invalid user or password",
    }
  }
  return {
    statusCode: 200,
    headers: {
      "Access-Control-Allow-Origin": "*", 
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ user}),
  };
};

you could chain the function inside the promise:你可以在 promise 中链接函数:

let fd = await new Promise((res, rej) =>
  User.findOne(
    {
      name: name,
    },
    (err, user) => {
      if (err) {
        rej({
          statusCode: 500,
          body: JSON.stringify({ msg: err.message }),
        });
      } else {
        bcrypt
          .compare(password, JSON.stringify(user.password))
          .then((match) => {
            if (match) {
              let statusCode = user && match ? 200 : 405;
              res({
                statusCode,
                headers: {
                  "Access-Control-Allow-Origin": "*",
                  "Content-Type": "application/json",
                },
                body: JSON.stringify({ user }),
              });
            }
          });
      }
    }
  )
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM