title: How to wait for an async function in javascript at top level?
body: <p>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:</p>
  
  <pre><code>const key = await get_async_data(config) // NOT RIGHT, can't use await at top level
  const api = new API(key)
  ... use api ...
  </code></pre>
  
  <p>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?</p>
  
  <p><code>API</code> is just a class exported by a module (which I control).</p>
  
  <p>(BTW I thought of putting the code to get the key into the <code>API</code> class's constructor, but of course constructors can't be async either.)</p>
  
  <p>I could make every async method of <code>API</code> set the key if unset, but that's pretty invasive and error-prone.</p>
  
  <p>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.</p>
  
  <p>Here's some more detail in case this helps.
  In api.js:</p>
  
  <pre><code>class API {
    constructor(key) {
      this.key = key
      // other stuff
    }
    async f1(a) {
    }
    async f2(b, c) {
    }
    f3() {
      return true
    }
  }
  export default API
  </code></pre>
  
  <p>Then in the places (many) where it'll be used:</p>
  
  <pre><code>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
  </code></pre>