доступ node.js hashmap после завершения его заполнения // AWS lambda

#node.js #amazon-web-services #asynchronous #amazon-s3 #promise

#node.js #amazon-веб-сервисы #асинхронный #amazon-s3 #обещание

Вопрос:

Итак, я работаю над лямбдой в AWS, и node.js это тоже ново для меня. Я совершенно уверен, что это связано с тем, что nodejs являются асинхронными и будут решаться с помощью promise / async / await, но никакое решение мне не помогает. Я перепробовал множество примеров, но не могу адаптировать их к тому, что у меня есть. Я очень упростил свой код до приведенного ниже:

 var fs = require('fs');
var es = require('event-stream');
let m = new Map();
const aws = require("aws-sdk");
let params = {...}; //details omitted, but refers to a csv file
let s3 = new aws.S3();

module.exports.handler = (event, context, callback) => {
   s3.getObject(params).createReadStream().pipe(es.split()).on('data'), (row) => {
       let dat = row.toString().split(',').map(function(x) {return x.trim() });
       m.set(dat[0], dat[1]); // there's actually around 100 lines of logic that I'm simplifying
   });
console.log(m.size);
  

Я понимаю, почему я всегда получаю размер 0, но я не могу найти обходной путь. Цель здесь после завершения заполнения карты — выполнить итерацию по ней и поместить все элементы в DynamoDB. (Я не делаю это напрямую, потому что есть много обновлений и потребуется много docClient.get / .query / .put) Мне просто нужно, чтобы карта была заполнена (другими словами, поток завершен). Я немного обеспокоен тем, что я слишком сильно упростил его, и часть ответа будет включать дополнительные обещания для логики, которую я пропустил, но я начну здесь, поскольку тестирование этого кода также дает размер 0.

И помощь была бы признательна, спасибо!

Ответ №1:

Да, проблема заключается в асинхронности. Структура вашего кода упрощена:

 // 1
s3.getObject(params).createReadStream().pipe(es.split()).on('data'), (row) => {
  ...
  // 3
});
// 2
console.log(m.size);
  

Выполнение следует за 1-2-3, поэтому консоль.регистрация происходит до поступления каких-либо данных. Вы можете прослушать событие закрытия и распечатать результат там:

 s3.getObject(params).createReadStream().pipe(es.split()).on('data'), (row) => {
  ...
}).on('close', () => {
  console.log(m.size);
}