Строка возврата из функции GET — AWS DynamoDB — Node.js

avatar
Jake Howard
8 апреля 2018 в 10:52
1886
2
2

это кажется очень простой операцией, и я уверен, что буду пинать себя, когда она будет решена!

Эта функция извлекает дату из базы данных Dynamodb из AWS Lambda под управлением Node.js 6.10. В другом месте он называется

.
var lastLogin = getLastLogin(UserId);

Глядя на консоль, она успешно извлекает дату, и я получаю "obj is 2018-04-08", но я просто не могу передать строку "obj" в переменную lastLogin.

function getLastLogin(UserId) {  
var docClient = new AWS.DynamoDB.DocumentClient();
var table = "REMOVED-FOR-PRIVACY";
var params = {
TableName:table,
Key:{
    "UserId": UserId,
}
};
console.log("Getting last login...");    
docClient.get(params, ((err, data) => {
if (err) {
console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2));
} else {
var payload = JSON.stringify(data, null, 2);
console.log ('payload content = ' + payload);
if (payload == '{}') {
console.log ('found nothing');
} else {
obj = JSON.parse (payload).Item.lastLogin;
obj = JSON.stringify(obj);
console.log ("obj is " + obj); // obj is 2018-04-08 
}}
return obj; }));
console.log("Returned date is " + obj); // Returned date is undefined
};
Источник

Ответы (2)

avatar
Khalid T.
8 апреля 2018 в 19:48
3

Во-первых, у вас есть пара проблем в вашем коде: вы ссылаетесь на obj вне его области видимости, что естественным образом приводит к undefined, плюс вы заключаете обратный вызов (функция стрелки) для get в дополнительная скобка.

Однако это не главная ваша проблема. Метод get — это асинхронный вызов, использующий интерфейс обратного вызова. Таким образом, ваша функция завершится до того, как get вернет какой-либо результат.

Вы можете попробовать использовать либо обратный вызов, либо обещание "thenable". Например:

function getLastLogin(userId) {
  const docClient = new AWS.DynamoDB.DocumentClient();
  const params = {
    TableName: "TABLE_NAME",
    Key: {
      "UserId": userId
    }
  };

  return docClient.get(params).promise();
}

let lastLogin;
getLastLogin(userId)
  .then((data) => {
    if (!data.Item || !data.Item.lastLogin) {
      console.log("User not found.");
    } else {
      lastLogin = data.Item.lastLogin;
      console.log("Last login: " + lastLogin);
    }
  })
  .catch((err) => {
    console.log(err);
  });
Jake Howard
9 апреля 2018 в 11:12
0

Блестяще, спасибо! Начинающий кодер понятия не имел, как насчет этого, но это имеет смысл!

avatar
Katie Fedoseeva
15 апреля 2021 в 16:42
1

Вы делаете вызов к базе данных, который всегда асинхронен. DynamoDB передает функцию обратного вызова в конец метода .get, который вызывается, когда возвращается результат, таким образом, значение передается замыканию, в котором вы его регистрируете. Однако код продолжает работать вне этой функции, не дожидаясь ее. В этом решении используются промисы, подобные приведенной выше реализации, но написанные немного по-другому, когда мы возвращаем значение новой переменной с именем «результат» после ее успешного разрешения. Переписано с использованием синтаксиса ES6.

const getLastLogin = UserId => {  
  const docClient = new AWS.DynamoDB.DocumentClient();
  const table = "REMOVED-FOR-PRIVACY";
  const params = {
    TableName:table,
    Key: {
      "UserId": UserId,
    }
  } ​
​
const result = new Promise((resolve, reject) => docClient.get(params, ((err, data) => {
 ​if (err) {
   ​console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2));
   reject(err);
 ​} 
 ​if (data) {
   ​resolve(data);
 ​}
})));

return result;
}