Skip to content

Commit

Permalink
Merge pull request #3 from akenneth/return-wrapped-promise
Browse files Browse the repository at this point in the history
Return consistent promise object for repeated calls with the same key
  • Loading branch information
keithamus authored Jan 18, 2021
2 parents 5eb4bbc + 1cf023a commit 260db15
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 4 deletions.
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

0 comments on commit 260db15

Please sign in to comment.