【发布时间】:2022-01-07 12:21:57
【问题描述】:
我是使用 NodeJS 无服务器的新手,我正在尝试使用异步函数来散列密码并在数据库中执行一些操作,问题是当我声明函数异步时,我总是收到此错误:
但是如果我在这里删除 async 关键字:
module.exports.login = async (event, context, callback) => {
函数运行正常,但我当然不能在函数中使用 Promise。
这是一个端点,用于进行 API 调用。
这是我的代码:
'use strict';
require('dotenv').config({ path: './.env' });
const dataBase = require('./utils/db');
const bcrypt = require('bcrypt');
const encryptPassword = async (plainPassword) => {
const saltRounds = 10;
const hashedPassword = await bcrypt.hash(plainPassword, saltRounds);
return hashedPassword;
};
module.exports.login = async (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false;
const parsedBody = JSON.parse(event.body);
const connect = dataBase.connectToDatabase();
const newPassword = await encryptPassword('test');
console.log(newPassword);
connect.query('SELECT * FROM users', (error, results, fields) => {
if (error) {
console.error(error);
callback(null, {
statusCode: 500,
body: JSON.stringify({
error: JSON.stringify(error),
message: 'Internal Server Error Booh!',
}),
});
}
if (results) {
callback(null, {
statusCode: 200,
body: JSON.stringify({
error: results,
message: 'No Error',
}),
});
}
});
};
这里是我的数据库连接和配置:
db.js
const mysql = require('mysql');
const isDev = true;
// Create mySQL Connection
const connectToDatabase = () => {
const pool = mysql.createPool({
host: isDev ? process.env.DATABASE_HOST_DEV : process.env.DATABASE_HOST_PROD,
user: isDev ? process.env.DATABASE_USER_DEV : DATABASE_USER_PROD,
password: isDev ? process.env.DATABASE_PASSWORD_DEV : DATABASE_PASSWORD_PROD,
database: isDev ? process.env.DATABASE_DATABASE_DEV : DATABASE_DATABASE_PROD,
multipleStatements: true,
});
return pool;
};
exports.connectToDatabase = connectToDatabase;
exports.mysql = mysql;
我错过了什么?
编辑:
这一切的目的,是因为我正在学习无服务器。
所有这一切都将在 AWS Lambda 中结束,并带有一个使用 API Gateway 的端点。
因此,当您调用此端点时,您将发送一些参数来注册/登录到应用程序。
我需要使用async/await,因为如果你注册一个账户,密码需要经过哈希处理,然后存储到数据库中,或者如果你登录,则需要比较密码,这两个操作都是异步的。
这就是为什么我需要端点是一个异步函数。
编辑 2:
阅读这篇文章:https://github.com/netlify/netlify-dev-plugin/issues/160
正如 Phil 提到的,异步和回调不应该一起使用,所以我像这样修改了我的代码,同样的错误:
'use strict';
require('dotenv').config({ path: './.env' });
const dataBase = require('./utils/db');
const bcrypt = require('bcrypt');
const encryptPassword = async (plainPassword) => {
const saltRounds = 10;
const hashedPassword = await bcrypt.hash(plainPassword, saltRounds);
return hashedPassword;
};
module.exports.login = async (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false;
const parsedBody = JSON.parse(event.body);
const connect = dataBase.connectToDatabase();
const newPassword = await encryptPassword('test');
console.log(newPassword);
connect.query('SELECT * FROM users', (error, results, fields) => {
if (error) {
console.error(error);
return {
error: 'some error to test',
};
}
if (results) {
return {
body: 'someBody',
};
}
});
};
最终功能代码:
如果想知道如何将这些查询作为承诺,这是我的方法,希望它可以帮助那些在同样情况下苦苦挣扎的人。
'use strict';
require('dotenv').config({ path: './.env' });
const dataBase = require('./utils/db');
const bcrypt = require('bcrypt');
const encryptPassword = async (plainPassword) => {
const saltRounds = 10;
const hashedPassword = await bcrypt.hash(plainPassword, saltRounds);
return hashedPassword;
};
module.exports.login = async (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false;
const parsedBody = JSON.parse(event.body);
const connect = dataBase.connectToDatabase();
const hashedPassword = await encryptPassword('test');
console.log(hashedPassword);
return new Promise((resolve, reject) => {
connect.query('SELECT * FROM users', (error, result) => {
if (error) {
reject(
callback(null, {
statusCode: 500,
body: JSON.stringify({
error: JSON.stringify(error),
message: 'Internal Server Error Booh!',
}),
})
);
}
if (result) {
resolve(
callback(null, {
statusCode: 200,
body: JSON.stringify({
data: result,
message: 'No Error',
}),
})
);
}
});
});
};
问候。
【问题讨论】:
-
encryptPassword似乎不是异步的,那么您为什么要等待呢?如果有什么东西是异步的,那就是dataBase.connectToDatabase(),但你还没有显示那个代码 -
你是对的,我已经更新了代码,哈希密码必须是一个异步/等待函数,同样的问题。
-
这里的用例并不完全清楚 - 这是作为 api 在外部调用还是在应用程序内部调用?
-
这将是一个 API 调用(它是一个端点),在外部。
-
好的,谢谢 - 这被称为“无服务器”,但这只是一个架构决定 - 此代码旨在以任何方式在服务器上运行,因此没有轴承。你在使用 express 之类的框架吗?它可能有助于回答你想去哪里
标签: node.js aws-lambda async-await serverless