Published: 2020-09-19
•
Did you know that async
/await
syntax is great for synchronous operations too? Really.
Let's say you want to perform some operations on a string:
let input = " some user input <script>alert('pwnd!');</script>"; input = input.trim(); input = sanitizeHTML(input); input = `You submitted <pre>${input}</pre>`; display(input);
This example is a bit contrived, but bear with me. The point here is that there are a number of self-contained operations we want to perform on our input string input
.
There's nothing wrong with the above example, however, reassigning a variable just doesn't feel quite right... what we have here is a functional pipeline, so it would be ideal to be able to model our code as a functional pipeline as well.
One way we could change this code is to add a pipe
function that will let us actually create a functional pipeline.
const pipe = (...fns) => fns.reduce((f, g) => (x) => g(f(x))); // Build up a functional pipeline const fn = pipe( x => x.trim(), x => sanitizeHTML(x), x => `You submitted <pre>${input}</pre>`, x => display(x), ); let input = " some user input <script>alert('pwnd!');</script>"; fn(input); // Run it
This is a valid approach and one I've used in the past many times. However, it has some drawbacks:
Now let's rewrite this functionality using promises.
const main = async (input) => { const x = await Promise.resolve(input) .then(x => x.trim()) .then(x => sanitizeHTML(x)) .then(x => `You submitted <pre>${input}</pre>`) display(x); }; main().then(() => console.log('Complete.'));
Look at that, all our operations neatly pipeline without any external libraries. What's more, we can now handle async operations and sync operations together in the same way.
Let's assume display
is an async operations. In the above example we could simply add an await
in front of it and our function would continue working as normally. Or we could include it in the pipeline:
Promise.resolve(input) .then(x => x.trim()) .then(x => sanitizeHTML(x)) .then(x => `You submitted <pre>${input}</pre>`) .then(x => display(x)) // Even if display is async this will work
Promises are pretty flexible, and can be used to model both sync and async operations without any external library code.
I write about life as well as my mistakes and successes as I learn to build a business. I'm building a self-funded startup (Pairwise).