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: ```JavaScript 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`. # How could we improve this? 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. ### Manual Functional Composition One way we could change this code is to add a `pipe` function that will let us actually create a functional pipeline. ```JavaScript 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: 1. This type of code is often opaque to new programmers or programmers without any background in functional programming. 2. For synchronous operations it requires building up a function even if you really just want to run a series of functions immediately and use the result. 3. For _async_ operations we can still use the approach above but may become harder to reason about and it will almost certainly exacerbate the first caveat, becoming less readable to outsiders. ## Promises can help Now let's rewrite this functionality using promises. ```JavaScript 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: ```JavaScript 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 ``` # The point Promises are pretty flexible, and can be used to model both sync and async operations without any external library code.