2

I would like to write a block of code using await syntax, immediately execute it, and create a promise that waits for execution to finish. I've come up with the following way to do this.

let makePromise = async () => {
    return foo && await bar();
}
let promise = makePromise();

However, I find this hard to read and understand. Creating a function and then calling it right away seems counter-intuitive and goes against good practice in other programming languages. Is there a more idiomatic way to write this piece of code?

Particularly, this code is used in the following context.

let promises = items.map((item) => {
    let makePromise = async () => {
        return foo(item) && await bar(item);
    }
    return makePromise();
});
cib
  • 2,124
  • 2
  • 21
  • 23
  • 1
    This is the only way. Why don't you hoist the temporary function to the module level, and give it some proper name based on its responsibilities and business value? Generally speaking, splitting up your code into multiple functions with thoughtful names is considered good practice. – Tamas Hegedus Jun 04 '18 at 09:27
  • Async functions actually return a promise. `const x = async () => {console.log(123)}; x.then(() => console.log(456))` – lipp Jun 04 '18 at 09:30
  • You should try `await`ing at `makePromise()` like this: `let makePromise = async () => { return foo && bar(); } let promise = await makePromise();` – Neeraj Wadhwa Jun 04 '18 at 09:40
  • @TamasHegedus Generally that might be true, but not in my case. I'll add some context to the question to make clear why your solution doesn't work in my case. That might also make it easier to answer the question. – cib Jun 04 '18 at 09:40
  • Possible duplicate of [Use async await with Array.map](https://stackoverflow.com/questions/40140149/use-async-await-with-array-map) – Tamas Hegedus Jun 04 '18 at 09:46
  • I see. That is one of the most-asked javascript questions here on SO. See https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call and https://stackoverflow.com/questions/36992590/asynchronous-map-function-that-awaits-returns-promise-instead-of-value/36993257 – Tamas Hegedus Jun 04 '18 at 09:49
  • Yeah, I know how to write this correctly, but I got here through partial refactoring of promise-based code, and didn't see the pattern immediately. So yeah, what I was trying to do was simply the wrong approach to begin with, that's why I ended up with weird code. – cib Jun 04 '18 at 09:59

2 Answers2

1

Why not using an async function directly? The following code behaves exactly the same as your example, but keep in mind, this results in an array of promises and awaits none of them.

function foo(x) { return "foo " + x; }
async function bar(x) { return "bar " + x; }
const items = [1];

let promises = items.map(
    async item => foo(item) && await bar(item)
);

Promise.all(promises).then(x => console.log(x));
Tamas Hegedus
  • 28,755
  • 12
  • 63
  • 97
  • 1
    Yup. My personal lessons learned: When I end up with code like this, I should probably try to look at the surrounding code and see if I can move the async declaration "further out", like in this case to the map callback. – cib Jun 04 '18 at 10:03
  • You can also find async versions of the `.map` function online, so in the end you could have sequential execution and control flow that is very similar to the good old synchronous version. – Tamas Hegedus Jun 04 '18 at 10:05
0

Async functions actually return a Promise. This is valid:

const x = async () => {
  console.log(123)
}

x().then(() => {
  console.log(456)
})

So in your case:

let promise = bar()
lipp
  • 5,586
  • 1
  • 21
  • 32