Let’s I have a function defined as below,
const crypto = require('crypto'); const fs = require('fs/promises'); const calculateHash = cache({ ttl: 5, size: 100 }, async file_path => { const buffer = await fs.readFile(file_path); return crypto.createHash('sha256').update(buffer).digest('base64'); }); const cache = (options, fn) => { return Object.assign(fn, { cache_size: () => { return 0; }, clear_cache: () => { // clear_cache is not implemented }, }); };
When I do console.log(calculateHash())
, it logs as,
[AsyncFunction (anonymous)] { cache_size: [Function: cache_size], clear_cache: [Function: clear_cache] }
…and when I do,
async function run() { const cache1 = await calculateHash('./fileToCache.js'); console.log(cache1) } run() .then(() => console.log('done')) .catch(e => console.error(e));
It actually calls the async function.
EB26xyw+zvLiccSc9Y3ZPDP0qqpBnNQsXdwyIFk8wPY= done
How does it work here?
When I do Object.assign(obj1, obj2)
, it will merge them; if properties are same it will override.
So, I think here Object.assign()
creates a final object as below
{ [AsyncFunction (anonymous)], cache_size: [Function: cache_size], clear_cache: [Function: clear_cache] }
But on calling calculateHash()
, how does it know to call the first property?
Advertisement
Answer
Functions are objects, and Object.assign
mutates it’s first argument and returns it:
const foo = {}; const bar = Object.assign(foo, { hi: 5 }); foo.hi; // 5 bar.hi; // 5 foo === bar; // true, foo and bar are the *same* object
If you do
const add3 = Object.assign(function(n) { return n + 3 }, { someValue: 42 }); add3(5); // 8 add3.someValue; // 42
Then add3
is still a function. You’re being led astray by what the console is showing you, that async anonymous function isn’t a property of the resulting object, it is the resulting object, with some stuff added to it. Note that “property” is in square brackets, and there’s no name associated with it.