繁体   English   中英

Express.js - 待定承诺阻止并延迟 express 中的下一个 GET 请求(Node.js)

[英]Express.js - Pending promise blocks and delays next GET request in express (Node.js)

我有一个正在运行的快速应用程序,它侦听 GET 请求。 任何 GET 请求都会立即返回一个成功响应并运行一个函数asyncForLoop() ,该函数返回一个在 5 秒后解析的承诺。

问题:即使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();
  }
}

您可以通过使用node运行脚本并在浏览器中打开两个地址为localhost:3005选项卡来测试上面的代码。 第一个选项卡将立即得到响应,而第二个选项卡加载 5 秒。

截屏

问题:为什么asyncForLoop()中的 promise 会延迟即将到来的请求? 不应该异步处理它,因为它在承诺中吗? 如何防止这种延迟的第二个请求?

谢谢!

JavaScript 是单线程的。 长时间运行的循环将阻塞您的所有代码。 您可以使用异步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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM