While async/await is great to make async commands look like synchronous ones, collection processing is not that simple. It's not just adding an async
before the function passed to Array.reduce
and it will magically work correctly. But without async functions, you can not use await
and provide a result later which is required for things like reading a database, making network connections, reading files, and a whole bunch of other things.
Let's see some examples!
When all the functions you need to use are synchronous, it's easy. For example, a string can be doubled without any asynchronicity involved:
const double = (str) => {
return str + str;
};
double("abc");
// abcabc
If the function is async, it's also easy for a single item using await
. For example, to calculate the SHA-256 hash, JavaScript provides a digest()
async function:
// https://developer.mozilla.org/docs/Web/API/SubtleCrypto/digest
const digestMessage = async (message) => {
const msgUint8 = new TextEncoder().encode(message);
const hashBuffer =
await crypto.subtle.digest("SHA-256", msgUint8);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray
.map(b => b.toString(16).padStart(2, "0"))
.join('');
return hashHex;
};
await digestMessage("msg");
// e46b320165eec91e6344fa1034...
This looks almost identical to the previous call, the only difference is an await
.
But for collections, handling asynchronicity becomes different.
To calculate the double for each element in a collection of strings is simple with a map
:
const strings = ["msg1", "msg2", "msg3"];
strings.map(double);
// ["msg1msg1", "msg2msg2", "msg3msg3"]
But to calculate the hash of each string in a collection, it does not work:
const strings = ["msg1", "msg2", "msg3"];
await strings.map(digestMessage);
// [object Promise],[object Promise],[object Promise]