Rie*_*u͢s 7 javascript design-patterns file-upload
我正在寻找一种解决方案来计算重复调用的每秒传输字节数function(下图).由于它的不准确,我不希望简单地除以经过的总时间的传输的字节:它造成了无法几分钟后运行,显示速度快的变化.
预设(大约每隔50ms调用一次):
function uploadProgress(loaded, total){
var bps = ?;
$('#elem').html(bps+' bytes per second');
};
Run Code Online (Sandbox Code Playgroud)
n几秒的平均每秒字节数,这是一个好主意吗?你的第一个想法是坏的,它被称为移动平均线,并且你可以定期调用你的更新函数你只需要保留一个队列(一个FIFO缓冲区)一个恒定长度):
var WINDOW_SIZE = 10;
var queue = [];
function updateQueue(newValue) {
// fifo with a fixed length
queue.push(newValue);
if (queue.length > WINDOW_SIZE)
queue.shift();
}
function getAverageValue() {
// if the queue has less than 10 items, decide if you want to calculate
// the average anyway, or return an invalid value to indicate "insufficient data"
if (queue.length < WINDOW_SIZE) {
// you probably don't want to throw if the queue is empty,
// but at least consider returning an 'invalid' value in order to
// display something like "calculating..."
return null;
}
// calculate the average value
var sum = 0;
for (var i = 0; i < queue.length; i++) {
sum += queue[i];
}
return sum / queue.length;
}
// calculate the speed and call `updateQueue` every second or so
var updateTimer = setInterval(..., 1000);
Run Code Online (Sandbox Code Playgroud)
避免计算速度突然变化的更简单方法是使用低通滤波器.PT1滤波器的简单离散近似是:

其中u[k]是输入(或实际值在样品)k,y[k]是输出(或滤波后的值在样品)k,并且T是时间常数(较大的T那个装置y将遵循u更慢).
那会被翻译成:
var speed = null;
var TIME_CONSTANT = 5;
function updateSpeed(newValue) {
if (speed === null) {
speed = newValue;
} else {
speed += (newValue - speed) / TIME_CONSTANT;
}
}
function getFilteredValue() {
return speed;
}
Run Code Online (Sandbox Code Playgroud)
两种解决方案都会给出类似的结果(至少为了你的目的),而后者似乎更简单(并且需要更少的内存).
另外,我不会快速更新值.过滤只会以50ms的刷新率将"闪烁"变为"摆动".我认为没有人希望以每秒一次(甚至几秒钟)的刷新率显示上传速度.