codejump
MediumPro challengeJavaScriptTypeScript

Node.js — From Callbacks to Promises

Node.jsBackendPromisesCallbacks

Before promises, Node APIs took an error-first callback: callback(error) on failure,
callback(null, result) on success. Many libraries still look like that, and
[`util.promisify`](https://nodejs.org/api/util.html#utilpromisifyoriginal) turns them into
functions you can await.

Your task

The driver hands you a legacy store with store.get(key, callback). Each call takes a few
milliseconds; a missing key fails with error.code === 'ENOKEY', a broken disk with
error.code === 'EIO'.

Write async getMany(store, keys):

  • Fetch every key in parallel — not one after the other. The driver measures how many calls

were in flight at once.

  • Return { values, missing }: values maps each found key to its value; missing lists

the keys that failed with ENOKEY, in the order of keys.

  • Any other error (EIO) rejects getMany itself.

The trap

store.get reads this.data. promisify(store.get) detaches the method from its object:
called later, this is undefined and it crashes with a TypeError. Bind it.

Example

// data: { a: 1 }   keys: ['a', 'zzz']
await getMany(store, ['a', 'zzz']);
// → { values: { a: 1 }, missing: ['zzz'] }       (driver adds maxInFlight: 2)

Sample tests

Test #1Two keys, in parallel
Input: [{"a":1,"b":"two"},["a","b"],[]]
Output: {"values":{"a":1,"b":"two"},"missing":[],"maxInFlight":2}
Test #2Missing keys
Input: [{"a":1},["a","zzz","yyy"],[]]
Output: {"values":{"a":1},"missing":["zzz","yyy"],"maxInFlight":3}
Test #3Disk failure rejects
Input: [{"a":1,"b":2},["a","b"],["b"]]
Output: {"error":"EIO"}
Test #4No keys
Input: [{},[],[]]
Output: {"values":{},"missing":[],"maxInFlight":0}