Как сделать вложенные вызовы DynamodB в лямбда-ноды? - PullRequest
0 голосов
/ 18 октября 2018

У меня были проблемы с вызовом функций async / await и возвращением этих данных для другой функции.

Как бы вы записали файл lambda nodejs, который:

A.Вызывает externalFile.js и ожидает ответного ответа со значением.(Вызывает DynamodB и спрашивает, сколько предметов у него есть, возвращает 10)

B.Как только возвращается 10, основная функция передает 10 в другой вызов Dynamodb, чтобы запросить номер 10.

или

CВызывается ExternalFile2.js, который async / ожидает ответа, а затем что-то выполняется с этим ответом.

По сути, идея заключается в том, что я хочу вернуть длину моей таблицы, затем запросить таблицу, затем обновить таблицу, все в асинхронном порядке, чтобы данные были доступны после первого вызова.

Как бы вы справились с этим?

Моя функция возвращает ноль и никогда не выполняет никаких вызовов console.logs Dynamodb

const AWS = require('aws-sdk');
var DOC = require("dynamodb-doc");
let totalMade = null;
let dbTotal = null;
let contractInfo = {};
var getTotalMade = require('./web3.js')

const dynamodb = new AWS.DynamoDB({apiVersion: '2012-08-10'});

async function get() {
    try {
        totalMade = await getTotalMade.data.methods.getTotal();
       console.log(totalMade)
        return totalMade.total
    }
    catch(error) {
        return error;
    }
}



exports.handler = async function(event, context) {

AWS.config.update({ region: "us-east-2" });
//Check External Contract for totalMade result
let tokenAddress = "0x32659521996926TEST"
let totalSupply = get().then(res => console.log("index results : "+ res))
console.log(" This is my results: this is the get(): " + totalSupply);

//Gets results from totalSupply and console logs properly, but cannot call dynamodb. Nothing executes

  //call DB with totalMade as an arguement 
   var params = {
       TableName: "XYZ123"
   }
    dynamodb.describeTable(params, function(err, data) {
        if (err) {
            console.log(err, err.stack);
          return err
        } else {

               if(ID > data.Table.ItemCount){
                console.log(ID, data.Table.ItemCount)

                  dbTotal = data.Table.ItemCount;
                  console.log("end of fetch: " + dbTotal + " and the SC total: " + ID)

                  var docClient = new DOC.DynamoDB();
                  contractInfo.allCards.forEach(item1 => {
                      console.log("running loop: " + item1)
                     docClient.putItem({
                    TableName: 'XYZ123',
                    ConditionExpression: 'attribute_not_exists(item1)',
                               Item: {
    'cardID' : item1,
    'numberID' : dbTotal++ ,
  }

                  }).promise()
                  .then((err, res) => {
                      if(err)console.log(err)
                      if(res) {

                        callback(null, {
                statusCode: '200',
                body: {
                res
                }
            });      }            
                  })
                  })


               }
               if(ID <= data.Table.ItemCount){
                 callback(null, {
                statusCode: '500',
                body: {
                  uptoDate: true
                }
            });                  
           }


     }






}).catch(err  => {
  console.log(err)
})

};

Мой внешний файл, который вызывает index.js:

     var tokenGen = require('./ERC721Generator.json');
    var ERC721a = require('./ERC721Token.json');
    var Web3 = require('web3');
    var web3 = new Web3(new Web3.providers.HttpProvider("https://rinkeby.infura.io/v3/API_KEY"));
    var version = web3.version.api; 
    const contract = require('truffle-contract');
    const tokenGenerator = contract(tokenGen);
    const ERC721 = contract(ERC721a);

    async function getItem(item){
       // Return new promise 
        return new Promise(function(resolve, reject) {
          // Do async job
           token.tokensArray().call(item, function(err, resp) {
                if (err) {
                    reject(err);
                } else {
                    resolve(JSON.parse(resp));
                }
            })
        })

    }
    var methods = {
      getTotal: async function() {

       tokenGenerator.setProvider(web3.currentProvider);
       ERC721.setProvider(web3.currentProvider);
     let contractInfo = {};  

    let token = await tokenGenerator.at("0xdf3d2033651212771a4f25d27d307e9f76de50b9")



//Can get this far, but nothing else runs after this
//Never gets into the while loop, why??



    let i = 0;
    contractInfo.total = await token.totalGenerated.call()
    while( i < contractInfo.total){
      getItem(i).then((err, res) => {
          contractInfo.allCards.push(res);
          console.log("inside loop" + contractInfo.allCards)
          i++
        })
      }

    return contractInfo
    }




    }


    exports.data = {
      methods
    }

1 Ответ

0 голосов
/ 18 октября 2018

Как насчет этого:

export default async (event, context, callback) => {
   [err,data ] = await promiseToObject(dynamoClient.put(//params).promise())

   if(err) {
     //handle err
     callback(err, null)

   }

  // results.Items has the returned data


  // do another await!

}

function promiseToObject(promise) {
    return promise.then((data) => {
        return [null, data]
    }).catch(err => [err])
}

Если это неясно, я обновлю, но в основном вы можете последовательно обрабатывать данные с помощью await, вам не нужны обратные вызовы, тогда и т. Д.

Обратите внимание, что PromiseToObject - это не мой код. Я приведу цитату как можно скорее!

Если вы хотите абстрагировать вызовы динамо в другой скрипт, вам просто нужно вернуть обещание из вызова DynamoDB, тогда вы можетежди.

...