【发布时间】: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 对我来说这就像假设的那样工作。尝试禁用所有扩展程序以确保不是因为其中之一。