44 lines
1.3 KiB
JavaScript
44 lines
1.3 KiB
JavaScript
/**
|
|
* Keep database waits and long scans visible without logging every record.
|
|
* update() also checks elapsed time when a synchronous loop delays timers.
|
|
*/
|
|
export function createProgress({ log = console.log, intervalMs = 5000, now = Date.now } = {}) {
|
|
if (!Number.isSafeInteger(intervalMs) || intervalMs < 1) throw new Error('进度输出间隔必须为正整数毫秒');
|
|
let message = '';
|
|
let startedAt;
|
|
let lastOutput;
|
|
let closed = false;
|
|
|
|
function output(force = false) {
|
|
if (closed || !message) return;
|
|
const current = now();
|
|
if (!force && lastOutput !== undefined && current - lastOutput < intervalMs) return;
|
|
lastOutput = current;
|
|
const seconds = Math.max(0, Math.floor((current - startedAt) / 1000));
|
|
log(message + '(已用时 ' + seconds + ' 秒)');
|
|
}
|
|
|
|
const timer = setInterval(() => output(), intervalMs);
|
|
timer.unref?.();
|
|
|
|
return {
|
|
stage(value) {
|
|
if (closed) return;
|
|
message = String(value ?? '').trim();
|
|
startedAt = now();
|
|
output(true);
|
|
},
|
|
update(value) {
|
|
if (closed) return;
|
|
message = String(value ?? '').trim();
|
|
if (startedAt === undefined) startedAt = now();
|
|
output();
|
|
},
|
|
close() {
|
|
if (closed) return;
|
|
closed = true;
|
|
clearInterval(timer);
|
|
},
|
|
};
|
|
}
|