首页 > 解决方案 > 如何在 lambda nodejs 中进行嵌套的 dynamodb 调用?

问题描述

我在调用 async/await 函数并将该数据返回给另一个函数时遇到了问题。

你将如何编写一个 lambda nodejs 文件,即:

A. 调用 externalFile.js 并等待带有值的返回响应。(调用 dynamodb 并询问它有多少项目,返回 10)

B. 一旦返回 10,主函数将 10 传递给另一个 dynamodb 调用,以查询数字 10。

或者

C. ExternalFile2.js 被称为异步/等待响应,然后使用该响应执行某些操作。

基本上这个想法是,我想返回我的表的长度,然后查询表,然后更新表,所有这些都在一个异步顺序内,以便从第一次调用中就可以使用数据。

你会怎么处理这个?

我的函数返回 null 并且从不执​​行任何 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 argument 
   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
    }

标签: node.jsaws-lambdaamazon-dynamodbaws-sdk

解决方案


这个怎么样:

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 不是我的代码,我会尽快提供引用!

如果你想将 dynamo 调用抽象到另一个脚本中,你只需要从 dynamoDB 调用中返回 Promise,然后你就可以等待它。


推荐阅读