consider this,
let value = "";
value = DATABASE_CALL();
module.exports = value;
When I require the above module in an another module and try to access the variable 'value', it is an empty string. How can I make the module.exports wait until the above DB call is completed and the variable is assigned a value?
CodePudding user response:
I assume value = DATABASE_CALL();
is a stand-in for asynchronous code. (If it were really synchronous as shown there, you'd just use it as the initializer value on value
.)
You have a few options for exporting a value that's only available asynchronously:
Using ESM instead of CommonJS and using top-level
await
to prevent he module from finishing loading until the database operation is complete.export default await DATABASE_CALL();
...where
DATABASE_CALL
returns a promise. (If it doesn't already, you can wrap it.)Code using it won't have to
await
it, but the module won't finish loading until the DB op is complete, and won't load at all if the DB op fails.This is really only appropriate if the module cannot be used at all without that value.
Exporting a promise of the value (whether you switch to ESM or keep using CommonJS):
module.exports = DATABASE_CALL();
...where (again)
DATABASE_CALL
returns a promise.Code using it would have to
await
the promise (or use explicit.then
/.catch
).Using ESM instead of CommonJS and using a flag value to indicate "not ready yet" (
null
andundefined
are useful for that) and updating the value when the database call is complete:export let value = null; // ...later when DATABASE_CALL is complete value = /*...the value from the DB...*/;
ESM exports are live bindings, meaning that if the source module updates the variable, imports in other modules see the updated value.
Note: You can only do this with named exports (
value
in the example), not default exports.Of course, that means the code using it has to allow for the possibility it's not loaded yet.
Exporting a function that provides the value, and that handles telling the caller the value isn't available yet (implementation left to the reader).
There are probably other choices.
In cases where the module is worthless without the asynchronous information, I usually use #1. If not, I usually use #2.