Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ export default function memoize<A extends unknown[], R extends unknown, T extend
return function (this: T, ...args: A) {
const id = hash.apply(this, args)
if (cache.has(id)) return cache.get(id)
const result = fn.apply(this, args)
cache.set(id, result)
let result = fn.apply(this, args)
if (result instanceof Promise) {
// eslint-disable-next-line github/no-then
return result.catch(error => {
result = result.catch(error => {
cache.delete(id)
throw error
})
}) as R
}
cache.set(id, result)
return result
}
}
33 changes: 33 additions & 0 deletions test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,39 @@ describe('memoize', () => {
expect(fn).to.have.been.called.with.exactly(noop)
})

it('returns the same Promise when called multiple times', async () => {
const memoized = memoize(a => Promise.resolve(a))
const p1 = memoized('1')
const p2 = memoized('1')
const p3 = memoized('1')
expect(p2).to.equal(p1)
expect(p3).to.equal(p1)
})

it('does not catch promises as a side-effect', async () => {
let failed = false
function setFailed() {
failed = true
}
process.on('unhandledRejection', setFailed)
const error = new Error('Rejected promise')
const memoized = memoize(() => Promise.reject(error))
let rejected = false
try {
await memoized()
} catch (e) {
if (e === error) {
rejected = true
} else {
throw e
}
}
expect(rejected).to.equal(true, 'Promise should reject when memoized')
await new Promise(setImmediate)
expect(failed).to.equal(false, 'Promise should not reject as a side effect')
process.off('unhandledRejection', setFailed)
})

describe('hash', () => {
it('calls hash to get key for cache store', () => {
let key = '1'
Expand Down