神刀安全网

elado/reuse-promise: Reuse the same promise that's returned from a function until it's resolved

reuse-promise

elado/reuse-promise: Reuse the same promise that's returned from a function until it's resolved elado/reuse-promise: Reuse the same promise that's returned from a function until it's resolved elado/reuse-promise: Reuse the same promise that's returned from a function until it's resolved

Purpose

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 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:

function findArticle(articleId) {   return fetch(`/article/${articleId}`).then(r => r.json())   // could also be   // return new Promise(...) }  // will issue first request for articleId=1 findArticle(1).then(article1 => console.log(article1)) // will issue second request for articleId=1 findArticle(1).then(article1 => console.log(article1)) // will issue first request for articleId=2 findArticle(2).then(article2 => console.log(article2))

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.

import { decorator as reusePromise } from 'reuse-promise'  class ArticleService {   @reusePromise()   find(articleId) {     return fetch(`/article/${articleId}`).then(r => r.json())   } }  const articleService = new ArticleService()  // will issue first request for articleId=1 articleService.find(1).then(article1 => console.log(article1)) // WILL NOT issue any request for articleId=1, will reuse the promise that was created in previous call articleService.find(1).then(article1 => console.log(article1)) // will issue first request for articleId=2 articleService.find(2).then(article2 => console.log(article2))

Wrapping a function

import reusePromise from 'reuse-promise'  function findArticle(articleId) {   return fetch(`/article/${articleId}`).then(r => r.json()) }  const findArticleReusedPromise = reusePromise(findArticle/*, options */)   // will issue first request for articleId=1 findArticleReusedPromise(1).then(article1 => console.log(article1)) // WILL NOT issue any request for articleId=1, will reuse the promise that was created in previous call findArticleReusedPromise(1).then(article1 => console.log(article1)) // will issue first request for articleId=2 findArticleReusedPromise(2).then(article2 => console.log(article2))

option: memoize

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:

import { decorator as reusePromise } from 'reuse-promise'  class ArticleService {   @reusePromise({ memoize: true })   find(articleId) {     return fetch(`/article/${articleId}`).then(r => r.json())   } }  const articleService = new ArticleService()  articleService.find(1).then(article1 => console.log(article1))  setTimeout(() => {   // here, the original promise is resolved   // without memoize: true, calling find(1) would go through original function and create a promise   // however, with memoize the following call will be immediately resolved with the value    articleService.find(1).then(article1 => console.log(article1)) }, 1000)

Clearing all memoized values of a function can be done with:

reusePromise.clear(articleService.find)  // or articleService.find.__reusePromise__clear()

Clear all:

reusePromise.clear()

Test

npm install npm test

License

MIT

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » elado/reuse-promise: Reuse the same promise that's returned from a function until it's resolved

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址