good-timing
v2.1.1
Published
Abstractions for easy timing composition with promise support.
Downloads
8
Readme
Quick Start
Install with preferred package manager
npm install --save good-timing
Import what you need
import { timeIn, sleep, atleast, defer, within } from "good-timing";
Remember to ⭐️ if this helps your project!
TimeDefintion
This package's central gimick.
While all helpers can accept a number of milliseconds, a better way to define duration is via the TimeDefintion
interface. It is simply an object containing any combination of the following keys.
| ms | second(s) | minute(s) | hour(s) | day(s) | weeks(s) | |:--:|:---------:|:---------:|:-------:|:------:|:--------:| | | sec(s) | min(s) | hr(s) | | wk(s) |
{ hour: 1, min: 5, seconds: 30 }
=>3930000ms
{ sec: 1 }
=>1000ms
{ hr: 2, sec: 50 }
=>7250000ms
{ second: 1, ms: 500 }
=>1500ms
API
Each of the exposed helper functions have overloads which tailor them to your specific use case.
Signatures are in typescript, everything in Bold
is a type, of which package-specific ones are referenced above, as well as in the Types Section.
timeIn
timeIn(time: TimeDefintion): number
Converts TimeDefintion
to number
of seconds. Easy!
const milliseconds = timeIn({ minutes: 15 });
// 900000
Note: This (or a sourced variable) can be used in place of any
Amount
, as it just returns a number of milliseconds.
sleep
More or less equivalent to setTimeout
sleep(time: Amount): Promise<number>
Return a promise which waits specified time. Resolves to number of milliseconds elapsed.
const howLongWasThat = await sleep({ seconds: 12 });
// Twelve suspense filled seconds later...
howLongWasThat;
// 12000
sleep(time: Amount, callback: Function): void
Run a callback after specified time.
sleep({ minute: 1 }, () => {
console.log("Hello to the future!")
});
// One minute later...
// A hello from the not too distant past! Truly amazing.
atleast
Useful where you want to ensure whatever you're waiting for takes a minimum amount of time.
Useful in situations where an operation may sometimes finish "too fast". If showing an animation while loading, for instance, it may be less-than-ideal for that animation to terminate before completing its first cycle.
atleast()
would give you the ability to set for how long that loading state should remain on screen, making time-of-flight feel more consistent.
atleast(time: Amount, promise: Promise<T>): Promise<T>
Resolve a promise only after specified time.
Will resolve as original promise does or after time
elapses, whichever is later.
const { log } = console;
const justASec = sleep({ sec: 1 })
const justAMinute = sleep({ min: 1 })
log(await atleast({ seconds: 30 }, justASec))
// 30 seconds later... (deferral was longer)
// > 1000
log(await atleast({ seconds: 30 }, justAMinute))
// 1 minute later... (original was longer)
// > 60000
atleast(time: Amount, executor: (resolve, reject) => void): Promise<Value>
Run function and return Promise resolving the async result. Will only resolve after time
has elapsed. More or less equivalent to new Promise()
but deferred.
await foo = atleast({ minute: 1 }, (resolve, reject) => {
setTimeout(() => resolve("bar"), 500)
});
// One minute later...
// foo === "bar"
defer
Delays the resolution of a promise by set time.
defer(time: Amount): (value: T) => Promise<T>
This function will add the amount of time specified, on top of existing time taken.
This is intended for use in
.then()
chains, as a passthrough. It can be added anywhere within to introduce some slowdown.
async function HelloLater(to: string){
await sleep({ sec: 5 });
return `Hello, ${to}!`
}
HelloLater("World")
.then(defer({ sec: 5 }))
.then(salutation => {
console.log(salutation)
});
// 10 seconds later...
// > Hello!
within
Returns a Promise
which only resolves if timeout is not reached, will reject instead if timeout is reached.
Useful to enforce a timeout on
Promisable
asyncronous operation.
within(timeout: Amount, awaiting: Promisable<T>): Promise<T>
This function takes awaiting
and resovlves as normal, so long timeout
is not reached.
If timeout elapses, output Promise will reject with the message
"Timeout: {number}ms"
;
async function HelloLater(to: string){
await sleep({ sec: 30 });
return `Hello, ${to}!`
}
await within({ sec: 29 }, HelloLater())
.catch(e => console.error(e))
// 29 seconds later...
// > "Timeout: 29000ms"
await within({ sec: 31 }, HelloLater())
.then(e => console.log(e))
// 30 seconds later...
// > 30000
within(defer: Amount, timeout: Amount, awaiting: Promisable<T>): Promise<T>
Resolves awaiting
only after defer
has elapsed, but only if timeout
has not.
Behaves exactly as
atleast(defer, within(timeout, awaiting))
async function justAMinute(){
await sleep({ sec: 60 });
return "foobar"
}
await within({ sec: 35 }, { sec: 60 }, justAMinute())
.catch(e => console.error(e))
// 60 seconds later...
// > "Timeout: 60000ms"
await within({ sec: 31 }, { sec: 62 }, justAMinute())
.catch(e => console.log(e))
// 61 seconds later...
// > 61000
Other Types
More data types encontered in API.
PromiseExecutor
A function containing asyncronous operation.
Equivalent to that consumed by
new Promise()
(resolve: (value) => void), reject: (reason) => void): void
Amount
Refers to anywhere TimeDefinition
or number
of milliseconds where interchangeable.
Promisable
Refers to anywhere Promise
or PromiseExecutor
are interchangeable.
License
MIT license.