This code implements a timer system that stores and manages multiple timers with their corresponding expiration times, allowing for functions to be executed at specified intervals. The system exports three functions: timeout for creating promises that resolve after a delay, delay for waiting for a specified time, and wait for conditional waiting.
npm run import -- "discord utilities"var timers = {}
var mainTimer = setInterval(callResolve, 20)
function callResolve() {
var now = Date.now()
var times = Object.keys(timers)
for(var i = 0; i < times.length; i++) {
if(now > times[i]) {
try {
Promise.resolve(timers[times[i]]())
} catch (e) {
console.log('timer failed', e)
throw e
}
delete timers[times[i]]
return
}
}
}
function addResolve(resolve, time) {
while(typeof timers[time] != 'undefined') {
time++
}
timers[time] = resolve
}
async function timeout(delay) {
var now = Date.now()
await new Promise(resolve => addResolve(resolve, now + delay))
}
async function delay(prev, delay) {
var now = Date.now()
if(now - prev < delay)
await new Promise(resolve => addResolve(resolve, now + (delay - (now - prev))))
return Date.now()
}
async function wait(until, delay) {
var waitTimer
var waitCount = 0
var result
var now = Date.now()
var delayed = now + delay
while(!result && now < delayed) {
await timeout(100)
result = await until()
now = Date.now()
}
return result
}
module.exports = {
timeout,
delay,
wait,
}
class TimerManager {
/**
* Creates a new instance of TimerManager.
*/
constructor() {
this.timers = {}
this.mainTimer = setInterval(this.callResolve.bind(this), 20)
}
/**
* Call resolve function for expired timers.
*/
callResolve() {
const now = Date.now()
const times = Object.keys(this.timers)
for (const time of times) {
if (now > Number(time)) {
try {
Promise.resolve(this.timers[time]())
delete this.timers[time]
} catch (e) {
console.log('timer failed', e)
throw e
}
}
}
}
/**
* Add a resolve function to the timer queue.
* @param {function} resolve - The resolve function to be added.
* @param {number} time - The time when the resolve function should be called.
*/
addResolve(resolve, time) {
while (this.timers[time]!== undefined) {
time++
}
this.timers[time] = resolve
}
/**
* Create a promise that resolves after a specified delay.
* @param {number} delay - The delay in milliseconds.
* @returns {Promise}
*/
async timeout(delay) {
const now = Date.now()
await new Promise(resolve => this.addResolve(resolve, now + delay))
}
/**
* Delay for a specified time.
* @param {number} prev - The previous time.
* @param {number} delay - The delay in milliseconds.
* @returns {Promise} The current time.
*/
async delay(prev, delay) {
const now = Date.now()
if (now - prev < delay) {
await this.timeout(delay - (now - prev))
}
return Date.now()
}
/**
* Wait for a specified condition to be met.
* @param {function} until - The condition to be met.
* @param {number} delay - The delay in milliseconds.
* @returns {Promise} The result of the condition.
*/
async wait(until, delay) {
let waitTimer
let waitCount = 0
let result
const now = Date.now()
const delayed = now + delay
while (!result && now < delayed) {
await this.timeout(100)
result = await until()
now = Date.now()
}
return result
}
/**
* Clean up the timer queue.
*/
cleanup() {
clearInterval(this.mainTimer)
this.mainTimer = null
this.timers = {}
}
}
module.exports = TimerManager timers is an object used to store timer functions with their corresponding expiration times.mainTimer is a timer that calls the callResolve function every 20 milliseconds.timers object and checks if the current time is greater than each expiration time.timers object.timers object with the current time plus the specified delay.addResolve function.wait function to repeatedly check the condition and wait for a short duration.timeout, delay, and wait.