Nodejs @awaitjs/express 怎么能够在 res.json()后继续完成一个长时间的任务

Nodejs @awaitjs/express 怎么能够在 res.json()后继续完成一个长时间的任务

我看到别人的提问里面

var express = require('express');
var app = express();

app.get('/some/route', (req, res)=> {
  res.json({success: false, message: "End time must be AFTER start time"});
  console.log('Hi')
});

这个 console.log('Hi')会被执行。现在我有一个需求,要用 [@awaitjs](/user/awaitjs)/express 来 decorate express,代码大概如下

const express = require('express');
const { decorateApp } = require('[@awaitjs](/user/awaitjs)/express');
const app = decorateApp(express());
const port = 3000;

function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }

app.getAsync(’/toggle’, async function(req, res){ let period = parseInt(req.query.period); let count = parseInt(req.query.count);

    res.json({success: true, message: "Power cycle schedueled successfuly for the interval of " + req.query.period + " minute(s), totaling " + req.query.count + " times."});
    while(count-- > 0){           
           await do_something();
    }
    
    
});

await app.listen(port, () => console.log(Example app listening on port ${port}!))

这个 res.json 后面的 while loop 是一个长时间执行的代码。我期望的是如前面第一个例子那样,在 res.json 返回客户端一个结果后继续执行 while loop。但是实际上这个 while loop 并不会运行,我哪里做的不对?


2 回复

不太建议你用这个 awaitjs/express,感觉实现不是很好。
你这个程序,后面用 while await,那么这个长时间任务没做完之前,这个 api 应该不会返回,就挂在那里,直到做完。
是这样吗?
如果是的,那你这么实现就不对了,你应该是要这个接口返回成功,然后程序还在跑。


在Node.js中使用Express框架时,如果在res.json()后需要继续执行一个长时间的任务,最佳实践是将这个任务放在后台执行,以避免阻塞事件循环并快速响应客户端请求。这通常通过任务队列或异步工作进程来实现。

以下是一个示例,展示了如何使用child_process模块在后台运行长时间任务:

const express = require('express');
const { fork } = require('child_process');
const app = express();

app.get('/long-task', (req, res) => {
  // 立即响应客户端
  res.json({ message: 'Task started' });

  // 创建一个子进程来执行长时间任务
  const worker = fork('worker.js');

  // 向子进程发送任务数据(如果需要)
  worker.send({ someData: 'your data here' });

  // 监听子进程的消息(可选)
  worker.on('message', (message) => {
    console.log('Task completed:', message);
  });

  // 处理子进程退出(可选)
  worker.on('exit', (code) => {
    console.log(`Worker process exited with code ${code}`);
  });
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

worker.js文件中,你可以处理长时间任务:

process.on('message', (data) => {
  // 执行长时间任务
  console.log('Received data:', data);
  // 模拟长时间任务
  setTimeout(() => {
    process.send({ result: 'Task completed' });
  }, 10000); // 10秒后完成任务
});

这样,你的Express服务器可以立即响应客户端,而长时间任务则在后台执行。

回到顶部