Created
July 30, 2020 15:11
-
-
Save glmdev/526c8b50fd7a276068cf43d634808973 to your computer and use it in GitHub Desktop.
TypeScript/JavaScript timeout handler - withTimeout
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
This is a simple function I wrote to make awaiting promises with timeouts easier. | |
Pass it in a timeout length and a promise, and you can attach handlers for when | |
the promise resolves on time, when it resolves late, and when the timeout expires. | |
Here's a snippet from one of my projects as an example: | |
withTimeout(request_timeout, this.kernel.handle(req)) | |
.on_time(output_req => { // called if it resolves on time | |
output_req.response.send() | |
}) | |
.late(output_req => { // called if it resolves late | |
this.logger.error(`Request timed out. Response was already sent on path: ${req.path}. Consider increasing server.request_timeout.`) | |
}) | |
.timeout(async () => { // called when the timeout expires | |
const factory = http(HTTPStatus.REQUEST_TIMEOUT) | |
const output_req = await factory.write(req) | |
output_req.response.send() | |
}) | |
.run() | |
Copyright (C) 2020 Garrett Mills <[email protected]>. | |
Licensed under the terms of the MIT license. | |
*/ | |
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>, | |
} | |
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 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment