【问题标题】:Express request fires a second time快速请求第二次触发
【发布时间】:2019-08-13 08:22:45
【问题描述】:

我在这里有点停顿。

我正在创建一个快递应用,它必须通过一个请求从 Shopify 商店导出大量数据。

问题是当我达到 2min 标记时,请求再次被触发(因为默认超时为 2min),所以我增加了 server.setTimeout() 以考虑它需要的时间。

所以这修复了请求在 2 分钟标记上的触发,但是一旦我的请求完成,由于某种原因再次发出第二个请求。

这是一个简单的问题示例:

const express = require('express');

function sleep(ms){
  return new Promise(resolve=>{
      setTimeout(resolve,ms)
  })
}

app.get('/export', async (req, res) => {
  // Sleep for 2:03min
  await sleep(123000);
  console.log('Starting request');
  res.status(200).send('Finish');
})

const server = app.listen(3000, () => {
  console.log(`Example app listening on port ${port}`)
})
// Set timeout to 2:04min
server.setTimeout(124000);

如果你打开http://localhost:3000/export上面代码返回的结果形式:

Starting request

Starting request

这是因为 async/await 的问题吗,因为 res.send() 似乎永远不会触发?

有人可以澄清“为什么”会发生这种情况以及“如何”防止这种情况发生吗?

PS:我无法使用标志或其他东西来检查请求是否已经发出,因为 APP 需要同时为用户导出数据和第二个请求工作作为一个全新的来。

【问题讨论】:

  • Did you try these things? 另外,尝试将其包装在 try-catch 中,以查看是否存在由于异步功能导致的任何静默错误
  • @Fredrik S 似乎问题在于请求被立即调用,对我来说它一直在无休止地调用它,所以似乎res.status(200).send('Finish'); 根本没有触发。
  • 在promise构造函数中,为什么没有reject参数而只有resolve?并且必须在 setTimeout 内调用 resolve,而不是作为要执行的函数传递。
  • @Kiran Mathew Mohan 所提供的示例只是展示问题的基础。我的代码中没有实际的睡眠,但我必须以某种方式发出 2 分钟的“虚拟”请求。 Promise 允许在没有拒绝的情况下解决,并且由于 resolve() 是一个函数,您可以将其称为 setTimeout 函数。你甚至可以这样称呼它Promise.resolve(),这也是有效的。
  • @drip 对我来说这就像假设的那样工作。尝试禁用所有扩展程序以确保不是因为其中之一。

标签: node.js express


【解决方案1】:

好吧,我今天在这件事上浪费了大约 4 个小时,结论是我的 Tunel 服务 (http://serveo.net/) 在导出完成后的某个时间点触发了另一个请求。 (至于为什么,我没有答案)我仍然不确定这是否是正确的结论,但切换到不同的选项(或使用直接 localhost )没有显示任何问题。

我搬到了 OpenVPN,我的所有问题都消失了。 Ngrok 也不错,但是由于免费版本没有固定的 URL(而且我每天启动服务时都要更改应用程序设置中的所有端点很痛苦),所以我选择了 OpenVPN。

问题的根源在于res.status(200).send('Finish') 从未因某种特定原因触发,或者如果确实如此,则似乎并非如此。

感谢大家的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-05
    • 2013-06-18
    • 1970-01-01
    • 1970-01-01
    • 2015-11-06
    • 1970-01-01
    • 1970-01-01
    • 2012-10-20
    相关资源
    最近更新 更多