不能在无服务器 NodeJS 函数中使用 Async/Await
Cannot use Async/Await in a Serverless NodeJS Function
我是使用 NodeJS 的无服务器新手,我正在尝试使用异步函数来散列密码并在数据库中执行一些操作,问题是当我声明异步函数时,我总是会收到此错误:
但是如果我在这里删除 async 关键字:
module.exports.login = async (event, context, callback) => {
该函数运行正常,但我当然无法在函数内使用 promises。
这是一个端点,可以进行 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 网关。
因此,当您调用此端点时,您将向 register/login 发送一些参数到应用程序中。
我需要使用async/await,因为如果你注册一个账户,密码需要被散列然后存储到数据库中,或者如果你登录,密码将需要被比较,这两个动作是异步的。
这就是为什么我需要端点是一个异步函数。
编辑 2:
正在阅读此 post:https://github.com/netlify/netlify-dev-plugin/issues/160
正如 Phil 提到的,async 和 callback 不应该一起使用,所以我修改了我的代码,同样的错误:
'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',
}),
})
);
}
});
});
};
此致。
快速浏览一下 the docs,您似乎不应该将 async
与 callback
arg 混合。只能使用其中之一,不能同时使用。
您可以迁移到 mysql2
库,这样您就可以使用 promises 或坚持使用现有的并使用 encryptPassword("test").then()
而不是 await
// no async
module.exports.login = (event, context, callback) => {
// remove this, you don't want it
// context.callbackWaitsForEmptyEventLoop = false;
const parsedBody = JSON.parse(event.body);
const connect = dataBase.connectToDatabase();
encryptPassword("test").then(newPassword => { // use .then()
console.log(newPassword);
// callback APIs are a pain, recommend migrating to mysql2 and use promises
connect.query('SELECT * FROM users', (error, results, fields) => {
if (error) {
console.error(error);
return callback(null, {
statusCode: 500,
body: JSON.stringify({
error: JSON.stringify(error),
message: 'Internal Server Error Booh!',
}),
});
}
callback(null, {
statusCode: 200,
body: JSON.stringify({
error: results, // error?
message: 'No Error',
}),
});
}
});
}
我是使用 NodeJS 的无服务器新手,我正在尝试使用异步函数来散列密码并在数据库中执行一些操作,问题是当我声明异步函数时,我总是会收到此错误:
但是如果我在这里删除 async 关键字:
module.exports.login = async (event, context, callback) => {
该函数运行正常,但我当然无法在函数内使用 promises。
这是一个端点,可以进行 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 网关。
因此,当您调用此端点时,您将向 register/login 发送一些参数到应用程序中。
我需要使用async/await,因为如果你注册一个账户,密码需要被散列然后存储到数据库中,或者如果你登录,密码将需要被比较,这两个动作是异步的。
这就是为什么我需要端点是一个异步函数。
编辑 2:
正在阅读此 post:https://github.com/netlify/netlify-dev-plugin/issues/160
正如 Phil 提到的,async 和 callback 不应该一起使用,所以我修改了我的代码,同样的错误:
'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',
}),
})
);
}
});
});
};
此致。
快速浏览一下 the docs,您似乎不应该将 async
与 callback
arg 混合。只能使用其中之一,不能同时使用。
您可以迁移到 mysql2
库,这样您就可以使用 promises 或坚持使用现有的并使用 encryptPassword("test").then()
而不是 await
// no async
module.exports.login = (event, context, callback) => {
// remove this, you don't want it
// context.callbackWaitsForEmptyEventLoop = false;
const parsedBody = JSON.parse(event.body);
const connect = dataBase.connectToDatabase();
encryptPassword("test").then(newPassword => { // use .then()
console.log(newPassword);
// callback APIs are a pain, recommend migrating to mysql2 and use promises
connect.query('SELECT * FROM users', (error, results, fields) => {
if (error) {
console.error(error);
return callback(null, {
statusCode: 500,
body: JSON.stringify({
error: JSON.stringify(error),
message: 'Internal Server Error Booh!',
}),
});
}
callback(null, {
statusCode: 200,
body: JSON.stringify({
error: results, // error?
message: 'No Error',
}),
});
}
});
}