[英]Express.js - Pending promise blocks and delays next GET request in express (Node.js)
I have a running express application which listens for GET requests.我有一个正在运行的快速应用程序,它侦听 GET 请求。 Any GET request immediately returns a success response and runs a function asyncForLoop()
which returns a promise which resolves after 5 seconds.任何 GET 请求都会立即返回一个成功响应并运行一个函数asyncForLoop()
,该函数返回一个在 5 秒后解析的承诺。
Problem: Even though asyncForLoop()
gets called after res.json()
any upcoming GET request afterwards gets delayed until the promise in asyncForLoop()
gets resolved.问题:即使asyncForLoop()
在res.json()
之后被调用,之后任何即将到来的 GET 请求都会被延迟,直到asyncForLoop()
的承诺得到解决。
const express = require("express");
const app = express();
app.listen(3005, () => {
console.log(new Date().getTime() + " running on port 3005.");
});
app.get("/*", (req, res) => {
myResponse(req, res);
});
function myResponse(req, res) {
console.log(new Date().getTime() + " GET request => " + req.originalUrl);
res.json({ success: true });
// this function blocks any following request until it is resolved
asyncForLoop().then(res => {
console.log(new Date().getTime() + " finished for-loop.");
});
}
function asyncForLoop() {
return new Promise(function(resolve, reject) {
// simulate a long synchronous action using wait() in a for-loop
for (let i=0; i<5; i++) {
console.log(i);
wait(1000);
}
resolve();
});
}
function wait(ms) {
let start = Date.now(),
now = start;
while (now - start < ms) {
now = Date.now();
}
}
You can test the code above by running the script using node
and opening two tabs with the address localhost:3005
in a browser.您可以通过使用node
运行脚本并在浏览器中打开两个地址为localhost:3005
选项卡来测试上面的代码。 The first tab will immediately get a response while the second tab loads for 5 seconds.第一个选项卡将立即得到响应,而第二个选项卡加载 5 秒。
Question: Why does the promise inside asyncForLoop()
delay upcoming requests?问题:为什么asyncForLoop()
中的 promise 会延迟即将到来的请求? Shouldn't it be handled asynchronously because it's inside a promise?不应该异步处理它,因为它在承诺中吗? How can I prevent this delayed second request?如何防止这种延迟的第二个请求?
Thanks!谢谢!
JavaScript is single-threaded. JavaScript 是单线程的。 A long running loop will block all your code.长时间运行的循环将阻塞您的所有代码。 You can use an asynchronous wait
function:您可以使用异步wait
函数:
const express = require("express");
const app = express();
app.get("/*", (req, res) => {
myResponse(req, res);
});
async function myResponse(req, res) {
console.log(new Date().getTime() + " GET request => " + req.originalUrl);
res.json({ success: true });
await asyncForLoop();
console.log(new Date().getTime() + " finished for-loop.");
}
async function asyncForLoop() {
for (let i=0; i<5; i++) {
console.log(i);
await wait(1000);
}
}
function wait(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
app.listen(3005, () => {
console.log(new Date().getTime() + " running on port 3005.");
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.