You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

56 lines
1.5 KiB

/**
* Base interface representing a timeout subscriber.
*/
export interface TimeoutSubscriber<T> {
on_time: (handler: (arg: T) => any) => TimeoutSubscriber<T>,
late: (handler: (arg: T) => any) => TimeoutSubscriber<T>,
timeout: (handler: () => any) => TimeoutSubscriber<T>,
run: () => Promise<T>,
}
/**
* Subscribe to a promise with a timeout.
* @param {number} timeout - timeout in milliseconds
* @param {Promise} promise - the promise to subscribe to
*/
export function withTimeout<T>(timeout: number, promise: Promise<T>) {
let on_time_handler: (arg: T) => any = (arg) => {}
let late_handler: (arg: T) => any = (arg) => {}
let timeout_handler: () => any = () => {}
const sub = {
on_time: handler => {
on_time_handler = handler
return sub
},
late: handler => {
late_handler = handler
return sub
},
timeout: handler => {
timeout_handler = handler
return sub
},
run: async () => {
let expired = false
let resolved = false
setTimeout(() => {
expired = true
if ( !resolved ) timeout_handler()
}, timeout)
const result: T = await promise
resolved = true
if ( !expired ) {
await on_time_handler(result)
} else {
await late_handler(result)
}
return result
}
} as TimeoutSubscriber<T>
return sub
}