我有两个不同版本的端点用于测试。第一个是:
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>
获取在浏览器中对我不起作用,但有一个网页发出这些请求可以