Node JS Асин c Выполнение - PullRequest
0 голосов
/ 12 июля 2020

Я новичок в обработке sh до Node Js и Asyn c. Я работаю над ботом Discord, интегрированным с AWS. Моя проблема заключается во всем, что я пробовал, async / await или упаковка в Promise не устранили проблему выполнения остальной части кода до завершения процесса asyn c. Вызовы AWS в основном асинхронные c, но я пытаюсь создать процесс syn c (проверка - элемент уже существует перед его добавлением). Прямо сейчас проверка не заканчивается вовремя, поэтому элемент будет добавлен повторно.

РЕДАКТИРОВАТЬ НИЖЕ МОЙ РЕДАКТИРОВАННЫЙ КОД И ВЫВОД

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
}

Ответы [ 2 ]

0 голосов
/ 12 июля 2020

в настоящее время проверяет 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()

и должна быть похожа на это с использованием обещаний (1-й аргумент успешно разрешен, 2-й - сбой базы запросов в документации)

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 вместо 2-го аргумента, но в async / await реализация см. ниже

 try {
   const response = await dynamodb.getItem(params).promise()
 } catch(err) {
  console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2));
 }
0 голосов
/ 12 июля 2020

Я не являюсь пользователем AWS, но если вы использовали Promise на одном этапе своих задач, это обычно означает, что вам нужно обрабатывать процедуру asyn c для каждого шага. Например:

async function doesServerExist(){
  const result = await aws.getDynamoDBItem(checkExistParams())
  return isEmptyObject(result)
}

Конечно, если вы хотите получить результат doesServerExist, вы также должны использовать ожидание перед его вызовом, чтобы получить результат асинхронно.

...