javascript - 如何防止 Nestjs 上的事件循环冻结?
问题描述
我正在尝试在 NestJs 中创建异步任务。我希望在向某个控制器发出一个请求后,我的异步任务开始在循环中开始你的长时间工作,然后节点/嵌套进程钢能够回答其他控制器的其他请求。
但是当异步循环开始时,Nest 的所有其他端点都被冻结,直到异步任务完成。
我已经尝试使用setTimeout()
, setInterval()
, setIntermmediate()
,queueMicrotask()
和Promise.resolve()
我的代码:
// Async task:
private checkTime(baseTime: number, startTimeStamp: number){
while(true){
const elapsedTime = Date.now() - startTimeStamp
console.log(`Elapsed time: ${elapsedTime}`)
if(elapsedTime > baseTime){
console.log(`Time excced!`)
break;
}
}
}
我已经尝试过这样的事情:
queueMicrotask(() => this.checkTime(edge.baseTime, startedTimeStamp))
setTimeout(() => this.checkTime(edge.baseTime, startedTimeStamp), 0)
解决方案
使用 javascript生成器
代码片段:
function* longTask(time = 1000) {
const startTime = Date.now();
// divides the long task into smaller chunks
yield startTime;
while (Date.now() - startTime < time) {
// process(): excute a small chunk of the task
// and yields the control back to the caller
yield Date.now() - startTime;
}
}
function completeLongTask(lt) {
const val = lt.next();
if (!val.done) {
setTimeout(() => {
completeLongTask(lt);
}, 0);
}
}
function triggerTask() {
const lt = longTask();
completeLongTask(lt);
}
triggerTask();
尽管上述解决方案有效,但我认为您不需要为您的用例使用生成器。看看这个更简单的解决方案是否适合您。
function checkTime(baseTime, startTimeStamp) {
const currentTimeStamp = Date.now();
const elapsedTime = currentTimeStamp - startTimeStamp;
console.log(`Elapsed time: ${elapsedTime}`);
if (elapsedTime > baseTime) {
console.log(`Time excced!`);
return;
} else {
setTimeout(() => {
checkTime(baseTime, startTimeStamp);
});
}
}
推荐阅读
- angular - 如何使用 PM2 流程启动/服务 Angular?
- angularjs - 获取标题的文本并将其分配给变量 Protractor
- google-maps - 获取特定点与谷歌地图上绘制的线之间的距离
- python - 为什么在加载大数据并且 RAM 内存不足时使用数据库(redis、SQL)会有所帮助?
- powershell - 如何从powershell中的配置文件中获取变量
- c++ - STL 容器的自定义分配器错误
- excel - 无法使用 VBA 复制 Excel 地图图表
- pandas - 将 pandas 数据帧与区间数据(自上而下)相结合,并创建具有最小可能区间的新 df
- xamarin - 如何在 Xamarin.forms 中显示来自视图模型的警报视图
- python - 用于函数式编程的 Pythonic 风格