首页 > 解决方案 > 处理需要 10 秒以上的 axios 请求

问题描述

我希望这个问题不是太笼统,但我有一个上传高分辨率图像的发布请求,然后在服务器端,对该图像进行多项操作以生成缩略图和水印。服务器需要 10-20 秒才能最终返回响应。我应该返回某种临时响应吗?这里有最佳实践吗?

为了便于说明,这里是客户端代码的粗略轮廓:

axios.post('/upload', hugePhoto, { headers: { 'Content-Type': 'multipart/form-data' } })
.then(res => { /* takes 10-20 seconds before I get a response here */ })
.catch(err => { /* handle error */ })

还有服务器端代码,注意我在这里创建了一堆不同大小的图像并将它们上传到 S3,这需要很长时间:

router.post('/upload', upload.single('file'), (req, res) => {
  sharp(req.file.path).metadata()
  .then(m => /* reading metadata */)
  .then(() => /* some db operations */)
  .then(() => /* uploading original file to S3 */)
  .then(() => /* resizing the file with sharp */)
  .then(() => /* uploading that to S3 */)
  .then(() => /* resizing the file with sharp */)
  .then(() => /* uploading that to S3 */)
  .then(() => /* resizing the file with sharp */)
  .then(() => /* uploading that to S3 */)
  .then(() => res.json({ success: true }))
  .catch(err => res.status(400).send(err.message))
})

谢谢!

标签: javascriptnode.jsajaxaxios

解决方案


这是使用无服务器事件驱动架构的完美用例。客户无需等到您创建和上传不同分辨率的图像。有多种方法可以减少时间。

  1. 并行而不是顺序地做事情。像这样的东西(您当前的架构不需要更改)
router.post('/upload', upload.single('file'), (req, res) => {
  sharp(req.file.path).metadata()
  .then(m => /* reading metadata */)
  .then(() => /* some db operations */)
  .then(() => /* uploading original file to S3 */)
  .then(() => Promise.all([funcResolution1(), funcResolution2(), funcResolution3()]))
  .then(() => res.json({ success: true }))
  .catch(err => res.status(400).send(err.message))
  1. 如果您乐于更改架构,则可以在此处利用无服务器技术。类似于 AWS Lambda ( https://aws.amazon.com/lambda/ )。你基本上从端点获取文件,然后引发一些事件让函数为你做其他事情。或者在 s3 上有一个触发器以在有文件时触发该函数。那个 lambda 函数可以为你做缩略图等。(https://aws.amazon.com/blogs/compute/resize-images-on-the-fly-with-amazon-s3-aws-lambda-and-amazon-api-gateway/

  2. 您可以将任务委托给其他应用程序,一旦有文件就会触发。

希望它能给你一些想法。


推荐阅读