Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to wait for an async function in javascript at top level?

I know this is a terrible idea. But I have an API which I can't use until I have a piece of data which I can only get asynchronously. Something like this:

const key = await get_async_data(config) // NOT RIGHT, can't use await at top level
const api = new API(key)
... use api ...

This is at top level, outside of any function, so I can't just await get_async_data() (it does return a Promise). Is there anything short of putting all my code in a giant async function so I can call await?

API is just a class exported by a module (which I control).

(BTW I thought of putting the code to get the key into the API class's constructor, but of course constructors can't be async either.)

I could make every async method of API set the key if unset, but that's pretty invasive and error-prone.

So I'm not really asking how to make my top-level code wait as much as I'm looking for alternative ways to structure this so the async call happens cleanly.

Here's some more detail in case this helps. In api.js:

class API {
  constructor(key) {
    this.key = key
    // other stuff
  }
  async f1(a) {
  }
  async f2(b, c) {
  }
  f3() {
    return true
  }
}
export default API

Then in the places (many) where it'll be used:

import API from '@/api'

const key = async get_key() // NOPE
const theAPI = new API(key)

async importantMethod(args)
{
  return await theAPI.f1(args)
}
async otherMethod()
{
  if (theAPI.f3)
    return await theAPI.f2(123)
  // etc...
}
// ... and so on
like image 533
GaryO Avatar asked Nov 28 '25 03:11

GaryO


1 Answers

Just use the Promise:

const pendingAPI = get_async_data(config).then(key => new API(key)); // N.B. no await
export default pendingAPI;

Meanwhile, in another file...

import pendingAPI from 'other/file';
pendingAPI.then(doStuffWithAPI);

There are times when async/await is a win. But never forget it's just sugar over Promises.

like image 138
Jared Smith Avatar answered Nov 29 '25 18:11

Jared Smith