Skip to content

Commit

Permalink
feat: promise
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Apr 20, 2021
1 parent 4747071 commit 7a755ce
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export * from './time'
export * from './types'
export * from './function'
export * from './object'
export * from './promise'
28 changes: 28 additions & 0 deletions src/promise.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { createSingletonPromise, sleep } from './promise'

it('promise', async() => {
let dummy = 0

const promise = createSingletonPromise(async() => {
sleep(10)
dummy += 1
return dummy
})

expect(dummy).toBe(0)

await promise()

expect(dummy).toBe(1)

await promise()
expect(await promise()).toBe(1)

expect(dummy).toBe(1)

promise.reset()

await promise()

expect(dummy).toBe(2)
})
52 changes: 52 additions & 0 deletions src/promise.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Fn } from './types'

export interface SingletonPromiseReturn<T> {
(): Promise<T>
/**
* Reset current staled promise.
* await it to have proper shutdown.
*/
reset: () => Promise<void>
}

/**
* Create singleton promise function
*
* @example
* ```
* const promise = createSingletonPromise(async () => { ... })
*
* await promise()
* await promise() // all of them will be bind to a single promise instance
* await promise() // and be resolved together
* ```
*/
export function createSingletonPromise<T>(fn: () => Promise<T>): SingletonPromiseReturn<T> {
let _promise: Promise<T> | undefined

function wrapper() {
if (!_promise)
_promise = fn()
return _promise
}
wrapper.reset = async() => {
const _prev = _promise
_promise = undefined
if (_prev)
await _prev
}

return wrapper
}

/**
* Promised `setTimeout`
*/
export function sleep(ms: number, callback?: Fn<any>) {
return new Promise<void>(resolve =>
setTimeout(async() => {
await callback?.()
resolve()
}, ms),
)
}

0 comments on commit 7a755ce

Please sign in to comment.