reuse-promise
Purpose
TL;DR - Prevent from a unique async process (function that returns a promise) to run more than once concurrently by temporarily caching the promise until it's resolved/rejected.
When a function returns a promise and it's being called from multiple places in the app, new promises are being instantiated, and multiple async operations are going to be executed.
A common case is a function that gets an articleId
and returns a promise that calls API. This function can be called from multiple places, each time will create a new promise and will issue a new request. This is usually not desired:
{ return // could also be // return new Promise(...)} // will issue first request for articleId=1// will issue second request for articleId=1// will issue first request for articleId=2
reuse-promise
decorates a function and temporary memoizes a promise until it's resolved. In this case, the first call for articleId=1
will create the new promise, issue the HTTP request, and remember that created promise for articleId=1
. The second call with the same argument will return the same promise from earlier call. However, once the original promise is resolved (or rejected), a new call to findArticle(1)
will issue a new request.
An initial call to a wrapped function goes through the original function, and then indexes the returned promise by a json-serialized string of the arguments that were sent to the function. So findArticles([1, 2, 3])
can be called twice and still return the same promise, becasue JSON.stringify([1, 2, 3]) === JSON.stringify([1, 2, 3])
.
Installation
npm install reuse-promise --save
Usage
reuse-promise
can be used as a decorator in a class definition or as a wrapper to a function.
As a class decorator
Requires babel
and babel-plugin-transform-decorators-legacy
plugin.
@ { return } const articleService = // will issue first request for articleId=1articleService// WILL NOT issue any request for articleId=1, will reuse the promise that was created in previous callarticleService// will issue first request for articleId=2articleService
Wrapping a function
{ return } const findArticleReusedPromise = // will issue first request for articleId=1// WILL NOT issue any request for articleId=1, will reuse the promise that was created in previous call// will issue first request for articleId=2
memoize
option: reuse-promise
can indefinitely remember the value that was returned from a promise, so no async code will execute more than once, even if the promise was previously resolved:
@ { return } const articleService = articleService
Clearing all memoized values of a function can be done with:
reusePromisecleararticleServicefind // orarticleServicefind
Clear all:
reusePromiseclear
serializeArguments
option: By default, reuse-promise
indexes promises in a dictionarty where the key is all arguments JSON.stringify
ied. This is sometimes an unnecessary process, especially when sending big objects as arguments.
A custom argument serializer can be provided. To reuse promises based on the first letter of the first argument, for example, provide:
@
Or, to grab an ID of a given model without having it all serialized:
updateUserName = const someUser = id: 1 name: 'name'
Test
npm installnpm test
License
MIT