Возвращение результата асинхронной операции c с веб-сервером Node.js - PullRequest
0 голосов
/ 07 января 2020

Я использую Express для создания веб-API. В следующем примере данные SVG преобразуются в PNG и загружаются в S3.

const svg2png = require("svg2png");
const AWS = require('aws-sdk');
const s3 = new AWS.S3();

app.post('/svg_to_png', function (req, res) {

  let params = req.body

  // STEP 1: Convert SVG to PNG:
  var outputBuffer = svg2png.sync(params.svg_data, {});

  // STEP 2: Upload to S3:
  let s3_params = {
      Bucket:params.bucket,
      Key:params.key,
      Body:outputBuffer,
      ContentType:'image/png',
      ContentDisposition:'inline',
      ACL: 'public-read'
  }
  result = s3.putObject(s3_params,function(err,data){
      if (err){
        return err;
      }
      return 'success';
  });

  // Return Image URL:
  let image_url = 'https://s3.amazonaws.com/' + params.bucket + '/' + params.key
  res.send(image_url)

})

Я хочу, чтобы API ответил URL-адресом преобразованного изображения, которое запрашивающий клиент может немедленно загрузить. Проблема заключается в том, что операция загрузки S3 выполняется асинхронно c, поэтому при доставке ответа изображение еще не существует в расположении URL-адреса, что вынуждает клиента опросить его существование.

Есть ли способ заставить веб-сервер отвечать только после завершения загрузки S3?

Ответы [ 2 ]

1 голос
/ 07 января 2020

Что примерно так:

const putObjPromise = s3.putObject(params).promise();
putObjPromise
  .then(data => {
    // Return the URL here.
  })
  .catch(err => console.log(err))

AWS имеет это сделать c для обещаний: https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/using-promises.html

Надеюсь, это поможет.

1 голос
/ 07 января 2020

, как упомянул @Brandon, вы можете вернуть ответ после завершения обратного вызова s3. Вы также можете использовать s3.putObject(params).promise(). Я предпочитаю это, так как это улучшает читаемость.

app.post('/svg_to_png', async function (req, res) {

  let params = req.body
  ...
  // STEP 2: Upload to S3:
  let params = {
      ...
  }

  try {
    const result = await s3.putObject(params).promise();
    // Return Image URL:
    // image_url = "https://s3.amazonaws.com/' + params.bucket + '/' + params.key

    // res.body(....).end()

  } catch(err) {
    // return error response
  }
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...