为什么服务器端点内的等待会阻止其他传入请求



我有两个不同版本的端点用于测试。第一个是:

app.get('/order', async (req, res) => {
console.log("OK")
getPrintFile()
})

第二个是:

app.get('/order', async (req, res) => {
console.log("OK")
await getPrintFile()
})

getPrintFile是一个异步函数,它在完成每个操作时返回一个promise。使用该功能,我将图像上传到服务器,我下载一个新的图像,并将该新图像重新上传到另一个服务器。

我注意到,在第一个例子中,在没有等待的情况下,如果我向";订单;端点,我得到了";OK";这就是我想要的,因为";OK";将被res.status("200"(取代。我需要以在由于各种原因得到端点命中之后立即发送状态200。然后,我不在乎服务器需要多长时间来完成图像/上传的所有处理,只要在有新的传入请求时立即执行res.send(200(即可。

然而,当我使用wait时,即使有新的请求传入,也需要花费大量时间来显示下一个";OK";如果以前的请求仍在处理中。通常,只有当getPrintFile函数中的代码执行完毕(即上传图像并完成所有操作(时,它才会显示OK

这就像事件循环被阻止了,但我不明白为什么。

这里发生了什么?

编辑:所以它更清楚,我测试了它;订单;端点;OK";立即在控制台中为所有请求显示,然后针对每个请求以自己的速度处理和上传图像。在第二个例子中,如果我发送了5个请求,则显示第一个OK,然后在执行完前一个请求时,一次显示一个剩余的4个,或者如果不是完全按照这个顺序,则会以巨大的延迟记录,并且不是连续的

我会根据我对您问题的理解来回答。缺少的第一件事是示例中的res.sendStatus(200),以使它们实际工作。但是,事实上,正如你所描述的那样:/order端点实际上是";"阻塞";由于await阻止您到达最终语句(res.send(,您无法再提出请求

const express = require("express");
const app = express();
async function takeTime() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("resolved");
resolve(1);
}, 2000);
});
}
app.get("/order", (req, res) => {
console.log("ok"); // Happens immediately
await takeTime();
return res.sendStatus(200);
});
app.get("/", async (req, res) => {
console.log("ok"); // Happens immediately
takeTime();
return res.sendStatus(200);
});
app.listen(3000, () => {
console.log("server running on port 3000");
});

当测试API(即来自Postman(时,您将无法立即在/order端点上运行另一个请求,因为您将被锁定等待刚刚发送的请求的答复。

另一方面,在/端点中,您将立即收到HTTP 200响应(因为没有等待(,并且takeTime函数的代码将保持异步运行,直到完成为止。

在这里你可以找到更多的信息,我希望它有用。

编辑1

在这里,我添加了用于测试await循环请求的.html页面

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body></body>
<script>
for (let i = 0; i < 10; i++) {
fetch("http://localhost:3000/order");
}
</script>
</html>

获取在浏览器中对我不起作用,但有一个网页发出这些请求可以

相关内容

  • 没有找到相关文章

最新更新