Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't cache rejected promises - fixes #8 #10

Merged
merged 3 commits into from Sep 25, 2017
Merged

Don't cache rejected promises - fixes #8 #10

merged 3 commits into from Sep 25, 2017

Conversation

SamVerschueren
Copy link
Collaborator

This PR fixes #8 by not caching a rejected promise by default. I also added a cacheRejection option (couldn't come up with a better name) to re-enable it.

Feedback welcome!

@kevva
Copy link

kevva commented Sep 20, 2017

I like cacheRejection or cacheRejected.

index.js Outdated
})
.catch(() => { });
} else {
cache.set(key, {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is duplicated. Can you extract it into an arrow function above the if statement on line 36?

readme.md Outdated
Type: `boolean`<br>
Default: `false`

Set to `true` if you want to cache rejected promises.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Set to true if you want to is moot. The default is defined, so we can just describe what it does:

Cache rejected promises.

test.js Outdated
}

return Promise.resolve(i);
});
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be simplified by using an async function:

const memoized = m(async () => {
	i++;

	if (i === 1) {
		throw new Error('foo bar');
	}

	return i;
}, {
	cacheRejection: true
});

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much better :)

@sindresorhus
Copy link
Owner

Let's go with cachePromiseRejection as cacheRejection can sound like it's about the rejection of the cache, not caching of the rejected promise.

@SamVerschueren
Copy link
Collaborator Author

Updated

@sindresorhus sindresorhus merged commit 6b99040 into master Sep 25, 2017
@sindresorhus
Copy link
Owner

Perfect 👌🌟

@LinusU
Copy link
Contributor

LinusU commented Sep 28, 2017

Hmm, it seems like this will wait to cache the value until the promise have settled, which is not how this module used to behave. I'm currently using the module something like this:

const getPlanInfo = mem(async (planName) => {
  const input = await expensiveApiCallThatFetchesPlanInfo()

  return { currency: input.currency.toUpperCase(), amount: input.amount }
}, { maxAge: A_FEW_HOURS })

In 1.x every request for a specific plan would all return the same Promise and only one request would go out to the remote server. In 2.x there will be one request sent per call until the first Promise settles.

p-memoize works by removing the Promise from the cache if the promise rejects (actually, it seems like it clears the entire cache when any promise rejects, since there is no way to clear a specific entry from the cache), which lets all the first requests use the single outgoing request to my third party service.


Would a PR to switch to returning the same pending Promise for all subsequent call until the promise settles be accepted?

@sindresorhus
Copy link
Owner

Would a PR to switch to returning the same pending Promise for all subsequent call until the promise settles be accepted?

Yes. This was just an oversight.

@LinusU
Copy link
Contributor

LinusU commented Sep 28, 2017

Great 👍

There is one small problem though 🤔

There is currently no specification that the provided cache must support .delete, even .clear is optional.

How do you want to solve this, should we add that it should provide .delete (which Map already does)?

edit: quick-lru also supports .delete so that's good 👍

@LinusU LinusU mentioned this pull request Sep 28, 2017
@LinusU
Copy link
Contributor

LinusU commented Sep 28, 2017

Submitted #12 which requires .delete to be present on the cache object

@LinusU
Copy link
Contributor

LinusU commented Oct 11, 2017

ping @sindresorhus 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Don't cache a rejected promise
4 participants