【问题标题】:Node JS Async Execution节点 JS 异步执行
【发布时间】:2020-07-14 20:20:57
【问题描述】:

我对 Node Js 和异步处理很陌生。我正在开发一个与 AWS 集成的不和谐机器人。我的问题是我尝试过的一切,异步/等待或包装在 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
}

【问题讨论】:

    标签: javascript node.js asynchronous promise aws-sdk


    【解决方案1】:

    我不是 AWS 用户,但如果您在任务的一个步骤中使用了 Promise,这通常意味着您需要处理每个步骤的异步过程。 例如:

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

    当然,如果你想得到doesServerExist的结果,你也应该在它调用之前使用await,来异步获取结果。

    【讨论】:

    • 我在上面编辑了我的代码。我正在按顺序从 AWS 获得响应,但是在 AWS 返回我要查找的项目后,输出冻结并且不会继续。我假设这与我的等待有关?
    【解决方案2】:

    目前正在查看 AWS 文档

    https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html#promise-property

    如果您使用promise,您似乎实际上不需要将回调函数传递给dynamodb.getItem,而是等待承诺解决/失败。

    所以这行代码是错误的

    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()
    

    并且应该像这样使用承诺(第一个参数成功解决,第二个是基于文档的请求失败)

    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 方法代替第二个参数,但在 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));
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-18
      • 2020-03-30
      • 2015-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-11
      • 1970-01-01
      相关资源
      最近更新 更多