返回Node.js web服务器异步操作的结果

返回Node.js web服务器异步操作的结果,node.js,express,Node.js,Express,我正在使用Express构建一个web 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:

我正在使用Express构建一个web 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上传操作是异步的,因此当响应被传递时,图像在URL位置还不存在,这迫使客户端轮询它的存在


有没有办法让web服务器只在S3上传完成后才响应?

正如@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
  }
})

正如@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
  }
})

像这样的东西怎么样:

const putObjPromise = s3.putObject(params).promise();
putObjPromise
  .then(data => {
    // Return the URL here.
  })
  .catch(err => console.log(err))
AWS有此承诺文件:


希望这有帮助。

像这样的东西怎么样:

const putObjPromise = s3.putObject(params).promise();
putObjPromise
  .then(data => {
    // Return the URL here.
  })
  .catch(err => console.log(err))
AWS有此承诺文件:


希望这能有所帮助。

在putObject回调中,只需调用
res.body(..).end()
@Brandon即可-谢谢!在putObject回调中,只需调用有效的
res.body(..).end()!由于某些原因,这会导致挂起的请求从未响应。请发布您当前的代码。这样我就可以看一看。还有你的节点版本是什么。仅节点8支持异步/等待。请参阅:。节点12声明了
结果
变量,更新了我的答案。如果它没有帮助,你能给我发送崩溃日志吗,谢谢你出于某种原因,这会导致一个永远不会响应的挂起请求。请发布你当前的代码。这样我就可以看一看。还有你的节点版本是什么。仅节点8支持异步/等待。请参阅:。节点12声明了
结果
变量,更新了我的答案。如果没有帮助,你能把事故日志寄给我吗,谢谢