node.js - 节点:在跟踪它运行多长时间的同时,每秒一致地运行函数 X 次
问题描述
我想编写一个自动化最大的系统。8192 个不同的值,每秒持续 40 次。我想做的那种自动化是例如让一些值形成一个从 0 到 255 的正弦曲线,其他的从 50 上升到 80,其他的在 255 和 0 之间切换等等。
我需要知道每次执行需要多长时间,如果执行时间超过允许的时间,它应该“丢帧”。
我的第一种方法是
// simplified code
const fps = 40
const executionStats : number[] = []
executionStats.length = fps * 10
const startFrame = new Date()
type SingleValue = {current: number, effectType: string, effectStarted: number}
const values : SingleValue[] = [...] // up to 8192 entries
// this is calculating the target value based on some lookups in other objects
// and based on when the effect started and in what tick we are in right now
const runSingleEffect = (value: SingleValue, tick: number) : number => {...}
const handler = async (tick: number) => {
values.forEach(value => {value.current = runSingleEffect(value, tick)})
}
setInterval(async () => {
const start = new Date()
await handler((start - startFrame) / fps);
const end = new Date()
executionStats.push(end - start)
executionStats.unshift()
}, 1000 / fps)
有没有比使用简单的更好的方法setInterval
?(显然我可以为执行统计使用环形缓冲区)但是有没有更好的方法来确保一次只运行一个处理程序?可能有那种东西的图书馆吗?
解决方案
我会使用setTimeout
连续重新订阅。您将在每个“循环”结束时重新计算下一个刻度。
function defer (ms) {
const frameBudgetMs = 1000 / fps;
setTimeout(async () => {
const start = Date.now();
try {
await handler((start - startFrame) / fps);
} finally {
const end = Date.now();
const ms = end - start;
executionStats.push(ms);
executionStats.unshift();
// a) In case we are over our frame, start next defer immediately.
let nextTickMs = Math.max(0, frameBudgetMs - ms);
defer(nextTickMs);
// b) In case we want to execute at specific frame interval, but just dropping the frames
let nextTickMs = frameBudget - ms % frameBudget;
defer(nextTickMs);
}
}, ms)
}
// start our loop
defer(0);
如您所见,您在重新订阅场景中是完全灵活的,在这样的“循环”中不可能有并行运行。
推荐阅读
- curl - Curl - 我们如何获得 POST 请求消息?
- sql-server - 将 varchar 值“YTLQVLBK”转换为数据类型 int 时转换失败。嵌套异常是 com.microsoft.sqlserver.jdbc.SQLServerException:
- python - 如何识别一个类定义节点是否是另一个类的扩展
- go - 如何解析查询字符串
- r - 创建一个分组条形图,每个类别只有一个填充
- javascript - 如何让函数变得简单
- amazon-web-services - 将 AWS elasticbeanstalk 重定向到另一个 elasticbeanstalk
- module - Discord.JS 宣布命令问题
- sql - 一次更新两个表,其中第一个表的值和一个变量
- r - 高于给定阈值的向量值的快速求和