我刚接触Node Js和异步处理。我正在开发与AWS集成的Discord机器人。我的问题是,我尝试过的所有事情,异步/等待或Promise的包装都没有解决在异步过程完成之前执行其余代码的问题。一般而言,AWS调用通常是异步的,但我正在尝试创建一个同步过程(在添加之前先检查是否已存在该项目)。目前,支票未及时完成,因此该商品被重新添加。
编辑 下面是我编辑的代码和输出
const AWSUtil = require("../utils/aws/awsUtil")
module.exports = async (client, message) => {
const aws = new AWSUtil()
const tableName = "Discord-Server"
let serverName = message.guild.name.replace(/[^a-zA-Z ]/g, "").replace(' ', '-')
let serverID = message.guild.id
if (message.member.hasPermission("ADMINISTRATOR")){
var doesExist = await doesServerExist()
console.log(`doesExist ----- ${doesExist}`)
if(!doesExist){
console.log("5 server is not already enrolled, adding the server...")
aws.addDynamoDBItem(addServerParams())
console.log("6 server successfully added")
message.reply(`${message.guild.name} has been successfully enrolled to SMSAlert!`)
} else {
console.log("5 server already enrolled...")
message.reply(`${message.guild.name} is already enrolled to SMSAlert.`)
}
} else {
return message.reply("You do not bave permissions to enroll the server.")
}
async function doesServerExist(){
console.log("1 Calling AWS util")
var response = await aws.getDynamoDBItem(checkExistParams())
//The below line never prints
console.log("4 Returning if server exists")
console.log(Object.keys(response))
return !Object.keys(response).length == 0
}
function addServerParams(){
return params = {
TableName:tableName,
Item:{
"server-id": serverID,
"server-name": serverName,
"topics":[]
}
};
}
function checkExistParams(){
return params = {
TableName: tableName,
Key:{
"server-id": { S: serverID }
}
};
}
}
以下是我的AWSUTIL课
var AWS = require('aws-sdk');
class AWSUtil {
constructor(){
AWS.config.loadFromPath('./config/aws/config.json');
}
async getDynamoDBItem(params){
console.log("2 Get Dynamo Item...")
const docClient = new AWS.DynamoDB.DocumentClient();
const awsRequest = await docClient.scan(params);
const result = await awsRequest.promise();
console.log(result.Items);
console.log("3 Returning getItem data")
return results.Items
}
async addDynamoDBItem(params){
console.log("Adding a new item...");
var docClient = new AWS.DynamoDB.DocumentClient();
const awsRequest = await docClient.put(params);
const result = await awsRequest.promise();
console.log("Added item:", JSON.stringify(result))
//docClient.put(params, function(err, data) {
//if (err) {
//console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2));
//} else {
//console.log("Added item:", JSON.stringify(data, null, 2));
//}
//});
}
removeDynamoDBItem(params){
console.log("Attempting to delete...");
var docClient = new AWS.DynamoDB.DocumentClient();
docClient.delete(params, function(err, data) {
if (err) {
console.error("Unable to delete item. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("DeleteItem succeeded:", JSON.stringify(data, null, 2));
}
});
}
}
module.exports = AWSUtil
下面是我的输出
1 Calling AWS Util
2 Get Dynamo Item...
[
My item
]
3 Returning getItem data
我的主文件中包含以下内容。
if (message.member.hasPermission("ADMINISTRATOR")) {
if (!doesServerExist()) {
console.log("server is not already enrolled, adding the server...");
aws.addDynamoDBItem(addServerParams());
console.log("server successfully added");
//return message.reply(`You have successfully enrolled ${message.guild.name} to SMSAlerts.`)
} else {
console.log("server already enrolled...");
//return message.reply(`${message.guild.name} is already enrolled to SMSAlert`)
}
} else {
return message.reply("You do not bave permissions to enroll the server.");
}
function isEmptyObject(obj) {
return !Object.keys(obj).length;
}
function doesServerExist() {
return isEmptyObject(aws.getDynamoDBItem(checkExistParams()));
}
以下是我的AWS通话
async getDynamoDBItem(params) {
console.log("Get Dynamo Item...")
var dynamodb = new AWS.DynamoDB({
apiVersion: '2012-08-10'
});
var response = null
await dynamodb.getItem(params, function(err, data) {
if (err) {
console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2));
} else {
response = data
}
}).promise()
return response
}
答案 0 :(得分:0)
我不是AWS用户,但是如果您在任务的一个步骤中使用了Promise,则通常意味着您需要为每个步骤处理异步过程。 例如:
async function doesServerExist(){
const result = await aws.getDynamoDBItem(checkExistParams())
return isEmptyObject(result)
}
当然,如果要获取doesServerExist
的结果,还应该在调用之前使用await来异步获取结果。
答案 1 :(得分:0)
当前正在检查 AWS文档
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html#promise-property
如果您使用dynamodb.getItem
,似乎您实际上不需要将回调函数传递给promise
,而是等待承诺解决/失败。
所以这行代码是错误的
await dynamodb.getItem(params, function(err,data){
if (err) {
console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2));
} else {
response = data
}
}).promise()
并且应使用promises来实现(第一个参数成功解析,第二个参数根据文档失败是请求的失败)
dynamodb.getItem(params).promise()
.then( function(data) {
response = data;
}, function(err) => {
console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2));
})
并且不确定是否可以使用catch
方法代替第二个参数,但是在异步/等待实现中请参见下文
try {
const response = await dynamodb.getItem(params).promise()
} catch(err) {
console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2));
}