簡體   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