Remembering a promise-based function

How can I memorize a promise based function?

Would memorizing a function be enough?

function foo() { return new Promise((resolve, reject) => { doSomethingAsync({ success: resolve, fail: reject }); }); }; 

is that enough?

 var fooMemoized = memoize(foo); 

Note. this question has been updated to remove a pending anti-pattern.

+6
source share
5 answers

Yes, that will be enough. Promises are simple return values, which is their biggest benefit - unlike callbacks where memoisation code would be horrible.

You may only want to make sure that the memorial promise cannot be analyzed if your promise library supports cancellation. Also note that this form of memoisation also remembers deviations, so you cannot recover from the “try again” errors.

+12
source

For promises, a simple memoize synchronization will not be good, because in most cases you do not want to remember errors (rejected by promises).

I made a simple library for general needs: https://github.com/nodeca/promise-memoize

  • This is a memoize function based on Promise, except for default errors
  • You can set the expiration time for the result.
  • If you need, you can also remember (and set the expiration time) for errors.
  • Data can be preprogrammed before the expiration date to never leave the cache cold.

Pseudocode:

 let db = require('mongoose').createConnection('mongodb://localhost/forum'); function lastPosts(limit) { return db.model('Post').find() .limit(limit).orderBy('-_id').lean(true).exec(); // <- Promise (thenable) } let cachedLastPosts = require('promise-memoize')(lastPosts, { maxAge: 60000 }); // Later... cachedLastPosts(10).then(posts => console.log(posts)); 
+4
source

Please note that your function has a deferred anti-pattern and can be simplified further:

 foo.value = null; function foo(){ if(foo.value) return foo.value; return (foo.value = doSomethingAsync()); } 

That is, memoization is so simple, in this case you do not even need to call .memoize . Also your original function suppresses errors.

+2
source

As @Bergi and @BenjaminGruenbaum pointed out, yes, the memories are wonderful, but it should be noted that your foo function does nothing useful and actually introduces errors (see deferred antipattern).

If all you want is to memoize the result of doSomethingAsync , you can cut out the average person:

 var fooMemoized = memoize(doSomethingAsync); 

Or, if you really simplify, and foo() passes arguments to doSomethingAsync , you can reduce it to one line:

 function foo() { return doSomethingAsync(argument1, argument2, etc.); } var fooMemoized = memoize(foo); 

Or, if you are not really planning on using foo() , you can do:

 var fooMemoized = memoize(function () { return doSomethingAsync(argument1, argument2, etc.); }); 
+2
source

Memory and promises are not obvious. Even worse with the new async / wait syntax.

to make it work like this:

 memoize(async () => 42) 

or

 const whatsTheAnswerToLifeTheUniverseAndEverything = () => 42 memoize(whatsTheAnswerToLifeTheUniverseAndEverything) 

You need a memoize function or library that supports promises and async syntax. A few of them: - https://github.com/aboutlo/async-memo-ize (Disclosure: I made this lib) - https://github.com/medikoo/memoizee

Note: Memoization is a cool technique, but you save CPU resources by consuming memory. You need to take care of how these libraries approach this issue on a scale;)

0
source

Source: https://habr.com/ru/post/1214316/


All Articles