简体   繁体   English

res.send 在将响应发送到我的 Express 服务器应用程序的前端之前,不会等待我的异步函数完成

[英]res.send is not waiting for my async function to finish before sending the response to the front end on my Express server app

I am trying to create full stack app that lets the user input the URL and captures the screenshot using Puppeteer.我正在尝试创建完整的堆栈应用程序,让用户输入 URL 并使用 Puppeteer 捕获屏幕截图。 On my backend express server I am using app.post to send the response to the front end which creates the image for download.在我的后端快速服务器上,我使用 app.post 将响应发送到创建图像以供下载的前端。

Here's my backend:这是我的后端:

app.post('/api/screenshot', (req, res) => {
  const { url } = req.body

  let screenshot = takeScreenshot(url)
  res.send({ result: screenshot })
  // next()
})

async function takeScreenshot(url) {
  const browser = await puppeteer.launch({
    headless: true,
    args: ['--no-sandbox']
  });
  const page = await browser.newPage();
  await page.goto(url, { waitUntil: 'networkidle0' });
  const screenshot = await page.screenshot()

  await browser.close();
  return screenshot;
}

My front end JS has an event listener for the ss-btn.我的前端 JS 有一个用于 ss-btn 的事件侦听器。 When it is clicked, it triggers the post request to the backend which runs the takeScreenshot function.当它被点击时,它会触发对运行 takeScreenshot 函数的后端的发布请求。 Then it generates the link for the download然后它会生成下载链接

$("#ss-btn").on("click", function (event) {
  event.preventDefault();
  var url = $("#url").val().trim();

  $.post("/api/screenshot", { url: url })
    .then(res => {
      const { result } = res
      const blob = new Blob([result], { type: 'image/png' })
      const link = document.createElement('a')
      link.href = window.URL.createObjectURL(blob)
      link.download = `your-file-name.png`
      link.click()
    })
});

Right now, when I click the ss-btn, I get the popup right away asking where I want to save the image.现在,当我单击 ss-btn 时,我会立即弹出窗口,询问我要将图像保存在哪里。 But it doesn't look like the screenshot is being sent back to the front end.但看起来截图并没有被发送回前端。 The png file is corrupted and I cannot open it. png 文件已损坏,我无法打开它。

TIA TIA

Try putting async/await function to execute your code one by one like this :尝试将 async/await 函数一一执行您的代码,如下所示:

 (async() => {
     
      let screenshot = await takeScreenshot(url)
      res.send({ result: screenshot })
    
  })();

The await function will execute your code and wait it to finish completely and return the final value then it will execute the next command inside the async function. await函数将执行您的代码并等待它完全完成并返回最终值,然后它将执行async函数内的下一个命令。

You have to await the result of takeScreenShot() .您必须await takeScreenShot()的结果。 It is an async function so it returns a promise that eventually resolves to your screenshot so to wait for it to complete and to get its value, you have to use either await or .then() on the promise it returns:它是一个async函数,因此它返回一个最终解析为您的screenshot的承诺,以便等待它完成并获取其值,您必须在它返回的承诺上使用await.then()

app.post('/api/screenshot', async (req, res) => {
  const { url } = req.body

  try {    
      let screenshot = await takeScreenshot(url)
      res.send({ result: screenshot })
  } catch(e) {
      // catch errors and send error status
      console.log(e);
      res.sendStatus(500);
  }
});

Changes:变化:

  1. Make request handler async so you can use await .使请求处理程序async以便您可以使用await
  2. Use await to wait for the screenshot result.使用await等待截图结果。
  3. Add try/catch to catch a rejection from the await .添加try/catch以捕获来自await的拒绝。
  4. Send error status if there's an error.如果有错误,发送错误状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM