API Node.Js ожидает завершения вызовов динамодба для отправки в браузер - PullRequest
0 голосов
/ 19 марта 2019

У меня сложный объем кода для динамических обращений к базе данных. По сути, у меня есть несколько вызовов базы данных, связанных в конце друг друга, и, кроме того, мне нужно перебрать несколько элементов. Затем в конце я должен иметь возможность отправить новый объект JSON во внешний интерфейс для правильного отображения. Проблема заключается в том, что Map завершается до завершения вызовов базы данных, поэтому переменная newItems не определена. В основном мне нужна карта, чтобы дождаться завершения базы данных, прежде чем перейти к следующей итерации.

Фрагмент кода - это не полный вызов, а соответствующая область. Это все также обернуто в app.get ().

        const newItems = items.map(function(item, i) {
          dynamoDb.scan({
            TableName: GIVEAWAY_ENTRIES_TABLE,
            FilterExpression: "giveawayId = :giveawayId",
            ExpressionAttributeValues: {
              ":giveawayId": item.id
            }
          }, (error, ge_result) => {
            dynamoDb.scan({
              TableName: USERS_TABLE,
              FilterExpression: "sessionId = :sii",
              ExpressionAttributeValues: {
                ":sii": sessionId
              }
            }, (error, result) => {
              dynamoDb.scan({
                TableName: GIVEAWAY_ENTRIES_TABLE,
                FilterExpression: "giveawayId = :giveawayId and userId = :userId",
                ExpressionAttributeValues: {
                  ":giveawayId": item.id,
                  ":userId": result.Items[0].id
                }
              }, (error, gemc_result) => {

                console.log("RESPONSEEEEEEE");
                return {
                  id: item.id,
                  title: item.title,
                  thumbnail: item.thumbnail,
                  photo: item.photo,
                  description: item.description,
                  myCount: gemc_result.Count,
                  totalCount: ge_result.Count
                }
              });
            });
          })

          console.log("END OF MAPPPPP");

        });

        console.log("#######", newItems);
        res.json({'success': true, data: newItems});

1 Ответ

3 голосов
/ 19 марта 2019

Первое, что я рекомендую вам, это использовать встроенную функцию promisify , чтобы функции AWS SDK возвращали promise. Это более читабельно! Затем вы можете воспользоваться обещаниями node.js для обработки асинхронного кода, вы можете использовать его так:

const util = require('util');
const safePromisify = function (fun, methodsArray) {
  const suffix = 'Async';
    methodsArray.forEach(method => {
      fun[method + suffix] = util.promisify(fun[method]);
  });
}
safePromisify(dynamoDb, ['scan']);

const newItems = items.map(function async(item, i) {
//                                  ^^^^^ this is required to use await

// Note the async and await keywords
  let ge_result = await dynamoDb.scanAsync({
    TableName: GIVEAWAY_ENTRIES_TABLE,
    FilterExpression: "giveawayId = :giveawayId",
    ExpressionAttributeValues: {
      ":giveawayId": item.id
    }
  });

  let result = await dynamoDb.scanAsync({
    TableName: USERS_TABLE,
    FilterExpression: "sessionId = :sii",
    ExpressionAttributeValues: {
      ":sii": sessionId
    }
  });

  let gemc_result = await dynamoDb.scanAsync({
    TableName: GIVEAWAY_ENTRIES_TABLE,
    FilterExpression: "giveawayId = :giveawayId and userId = :userId",
    ExpressionAttributeValues: {
      ":giveawayId": item.id,
      ":userId": result.Items[0].id
    }
  });

  return {
    id: item.id,
    title: item.title,
    thumbnail: item.thumbnail,
    photo: item.photo,
    description: item.description,
    myCount: gemc_result.Count,
    totalCount: ge_result.Count
  }
});

Примечание: Вы должны добавить слово Async к вызову функции

...