admin管理员组

文章数量:1287597

I tried finding the solution to my problem, but couldnt find it, and was looking for some "best practice examples". I have a nodejs express application and my functions are split in files. For example I have this controller (oktacontroller.js):

var okta_api_key = <here some await data, getting from db>;

const OKTA_ORG_URL = '<here too>';

exports.createUser = async (req, res) => {

    console.log(okta_api_key);
}

exports.getGroups = async (req, res) => {
    console.log(okta_api_key);
}

In both exported functions (which are express routes) I need the var okta_api_key. I know I can get them by querying them in both functions, because they are async functions and I can use await there, but it feels dumb to query this every time (because it wont ever change).

How can I manage this? I know I can do this:

var okta_api_key;
(async () => {
    okta_api_key = await <getting key async>
})()

But this feels off as well..

Is there any way too make some sort of large function, which is async, and exports the two functions? In other words: How do I use await on the top level of a file (module). It doesnt need to be on top level (its impossible), but some sort of method to have my "top level" variables exposed to my exported functions.

EDIT: Some other usecase, because I got the suggestion of putting it in a config file. Yes, for this one it is possible, but for example: I have some other api key which gets his access token from the service itself, on every startup (because it expires). That token cannot be stored in the config file, so I need some async work to get the value. I know top-level-await is not working (or even not desirable), but I just want an example of how you guys would do this if it were your project :)

I tried finding the solution to my problem, but couldnt find it, and was looking for some "best practice examples". I have a nodejs express application and my functions are split in files. For example I have this controller (oktacontroller.js):

var okta_api_key = <here some await data, getting from db>;

const OKTA_ORG_URL = '<here too>';

exports.createUser = async (req, res) => {

    console.log(okta_api_key);
}

exports.getGroups = async (req, res) => {
    console.log(okta_api_key);
}

In both exported functions (which are express routes) I need the var okta_api_key. I know I can get them by querying them in both functions, because they are async functions and I can use await there, but it feels dumb to query this every time (because it wont ever change).

How can I manage this? I know I can do this:

var okta_api_key;
(async () => {
    okta_api_key = await <getting key async>
})()

But this feels off as well..

Is there any way too make some sort of large function, which is async, and exports the two functions? In other words: How do I use await on the top level of a file (module). It doesnt need to be on top level (its impossible), but some sort of method to have my "top level" variables exposed to my exported functions.

EDIT: Some other usecase, because I got the suggestion of putting it in a config file. Yes, for this one it is possible, but for example: I have some other api key which gets his access token from the service itself, on every startup (because it expires). That token cannot be stored in the config file, so I need some async work to get the value. I know top-level-await is not working (or even not desirable), but I just want an example of how you guys would do this if it were your project :)

Share Improve this question edited May 30, 2019 at 15:06 Eric Jansen asked May 30, 2019 at 14:48 Eric JansenEric Jansen 4401 gold badge6 silver badges23 bronze badges 5
  • 2 Not at present, it's still a Stage 2 proposal and I would suggest reading this: Top-level await is a footgun. – zero298 Commented May 30, 2019 at 14:50
  • 2 If it never changes why does it need to be stored in the db? Just put it in a config file and import it into your module. – Isaac Vidrine Commented May 30, 2019 at 14:55
  • Yeah, but I can (and want to) change settings via the GUI (my app) – Eric Jansen Commented May 30, 2019 at 15:01
  • 1 Simple. set var okta_api_key to a promise, which you can await as many times as you want without actually performing the async task over and over. – Kevin B Commented May 30, 2019 at 15:13
  • So just say const okta_api_key = doSomethingAsync() and then in the functions say const real_api_key = await okta_api_key()? – Eric Jansen Commented May 30, 2019 at 15:16
Add a ment  | 

1 Answer 1

Reset to default 11

You are close:

 var okta_api_key = (async () => {
    return  await <getting key async>
 })();

Create a promise, then await that promise whenever you want to use it.

How do I use await on the top level of a file (module).

Top level await might look great: You just add one await and then you can access the variable synchronously. But that simplifies things too much: It will stop all modules depending on that module from executing. In most cases you don't want that¹. Instead create a promise of the async task, then await it when needed. That way you limit the asynchronous execution to the code pieces that actually need it.


¹ Those rare cases are:

1) Loading some global config, that you have to access everywhere in your code, so it makes no sense to start the service if the config isn't ready.

2) awaiting in the top level file of your service: As no module depends on it, this won't cause any problems.


Side note: Top level await is not yet specified, and the NodeJS support is also not there yet. To use it in production you have to wait a few months (?).

本文标签: nodejsJavascriptNodejs use await on top level in nodejs moduleStack Overflow