node.js - 如何在 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
}
解决方案
这个怎么样:
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,然后你就可以等待它。
推荐阅读
- python-3.x - 未按数字排序时如何获取网站链接
- html - 如何使用 Jquery 和 CSS 在兄弟 div 上打开 div
- excel - 有没有更好的方法来做到这一点(Excel)
- flutter - 带有 navigatorKey 和密钥的 Flutter MaterialApp 未重新启动
- javascript - 用vue上传多个动态文件
- node.js - 在开始 mocha 测试之前确保 express 应用程序正在运行
- rust - Rust - 嵌套循环只在内循环内执行一次
- apache-flink - 提高 Flink 广播性能
- javascript - 我收到类似 index.js:1 的错误警告:超出最大更新深度
- c# - Task<> 在 Net Framework 4.0 中不包含“GetAwaiter”的定义