1

Is there a way, in a JavaScript object literal, to initialize some fields with the result of async functions while ensuring they will still run concurently?

Here is what I tried:

async function f() { /* ... */; return 0; }
async function g() { /* ... */; return 1; }

async function init() {
  const o = { f: f(), g: g() };
  return o;
}

init().then(console.log)
//> { f: Promise { ... }, f: Promise { ... } }
// XXX not what I want: I want *values* not promises

If I write the code above, f() and g() are resolved in parallel, but obj.f and obj.g will hold the promise returned by the function, not the resolved value.

On the other hand, with the syntax below I obtain an object whose fields contains values, but it seems to me the f() and g() calls were resolved sequentially. Or am I wrong here?

async function init() {
  const o = { f: await f(), g: await g() };
  return o;
}

init().then(console.log)
//> { f: 0, g: 1 }
// ??? did `f()` and `g()` run concurrently or sequentially here?
Sylvain Leroux
  • 50,096
  • 7
  • 103
  • 125

1 Answers1

3

No, you need to use Promise.all to wait for multiple concurrent things:

async function getF() { /* ... */; return 0; }
async function getG() { /* ... */; return 1; }

async function init() {
  const [f, g] = await Promise.all([getF(), getG()]);
  return {f, g};
}

init().then(console.log);
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Why won't the two `await` calls in the `init()` function work like any sequence of `await` calls would work in an `async` function? (The second version of the OP code.) – Pointy Jan 25 '19 at 15:17
  • @Pointy They do work, but as you say they are *sequential*. OP wanted to ensure that the functions run concurrently. – Bergi Jan 25 '19 at 15:22
  • 1
    oh ~ light bulb ~ because the second one won't start until the first resolves, got it. – Pointy Jan 25 '19 at 15:29