AWS Lambda возвращает значение «ноль» после прохождения цикла forEach для сохранения нескольких файлов в корзину s3 - PullRequest
0 голосов
/ 25 сентября 2018

У меня есть функция AWS Lambda.Он просматривает список массива, который является массивом URL-адресов, сохраняет их скриншот и помещает их в s3.Как мне вернуть выходные данные этой функции, которая является массивом screenshotLinks, в котором есть все ссылки на файлы, сохраненные в s3?Я использовал функцию обратного вызова в конце, но она просто возвращает нольЯ хочу, чтобы функция обратного вызова выводила все ссылки на файлы s3, сохраненные в массиве screenshotLinks.

exports.handler = (event, context, callback) => {

desktopLinks.forEach(function (url, index) {
      https.request(url, function(res) {
        var data = new Stream();
        res.on('data', function(chunk) {
          // Agregates chunks
          data.push(chunk);

        });

        res.on('end', function() {
          var body = data.read();
          // Once you received all chunks, send to S3
          var currentLink = links[index];
          var linkAddress = encodeURIComponent(currentLink);
          var slashPosition = getPosition(currentLink, '/', 3)+1;
          var linkName = currentLink.substr(slashPosition, currentLink.length)
          var params = {
            Bucket: bucket,
            Key: completeDate + '/screenshots/' + linkName + '.png',
            Body: body
          };
          s3.putObject(params, function(err, data, callback) {
            if (err) {
              console.error(err, err.stack);
            } else {
              bunch = params.Bucket + '/' + params.Key;
              screenshotLinks.push(bunch);
            }
          });
        });
        
      }).end();
     
  })
  callback(null, screenshotLinks)
};

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

Я хотел бы предложить вам использовать среду выполнения 8.10.

ref: https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/

Тогда ваша точка входа должна быть:

export async function <function_name>(event) {}

Тогда:

let s3 = new AWS.S3({ region: process.env.AWS_REGION, apiVersion: '2006-03-01' });
let params= 
{
     Bucket: /* a path to bucket (string) */,
     Key: name /* string */,
     Body: /* supported types (Buffer, Typed Array, Blob, String, ReadableStream) */,
     ACL: 'public-read',
     ContentType: 'image/png'
};

try
{
    let s3Response = await s3.upload(params).promise();
    // if succceed
    console.log(`File uploaded to S3 at ${s3Response.Bucket} bucket. File location: ${s3Response.Location}`);
}
catch (ex) // if error occured
{
    console.error(ex);
}
0 голосов
/ 25 сентября 2018

Ваш код является управляемым событиями / асинхронным, что означает, что вы вызываете обратный вызов до того, как будут заполнены screenshotLinks.

Метод узла http.ClientRequest.end () заканчивает отправку запроса, но это не означает, что ответ был получен и обработан, как это делается асинхронным событиемобработчик.Однако обратный вызов выполняется сразу после вызова метода request.end (), то есть сразу после того, как запрос был запущен, поэтому screenshotLinks пуст.

Вам необходимо выполнить обратный вызов из пройденного вами обратного вызовав s3.putObject.Я предлагаю вам передать свой обратный вызов объекту ответа / результата, который указывает, успешно ли был выполнен putObject и содержит ли URL-адрес, к которому он относится, и либо сообщение об ошибке, либо screenshotLink, например что-то вроде этого:

      s3.putObject(params, function(err, data, callback) {
        var s3Response;
        s3Response.url = url;
        if (err) {
          s3Response.success = false;
          s3Response.error = err;
          console.error(err, err.stack);
        } else {
          bunch = params.Bucket + '/' + params.Key;
          s3Response.success = true;
          s3Response.screenshotLink = bunch;
        }
        callback(null, s3Response);
      });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...