我读了很多书,但还没有找到一个有效的解决方案
我看到的最接近的是:导出React 中异步函数的结果
请记住,我想导出一个对象,而该对象是异步函数的结果,而不是导出异步函数定义本身
以下是我到目前为止的用例和实现:
-
我们有一个名为config.ts 的文件
-
传统上,config.ts包含一个具有相关运行时配置的对象作为默认导出
这让我们可以简单地使用
import config from '../config'
或任何 -
我们的配置和秘密管理变得更加复杂,因此需要对各种秘密存储库(aws、azure等(进行各种调用
-
我重构了config.ts,现在看起来像这样:
export const basicValues = {
color1: 'red'
}
async function buildConfig(){
const valuesOut = {...basicValues}
valuesOut.color2 = await getSecret('color2');
valuesOut.color3 = await getSecret('color3');
return valuesOut;
}
export default buildConfig()
其中getSecret
是使任意异步调用的某个函数
我导出上面的basicValues,因为我有一些配置设置,这些设置是在getSecret中进行调用所必需的。
通过像这样导出basicValues,我可以用一个简单的const basicConfig = require('../config').basicValues
来获取这些值。通过这种方式,我们可以继续在一个干净、集中、经过测试的文件中管理所有有趣的配置,但仍然可以很早地使用这些值,并避免周期性依赖
总之,这感觉它应该工作
我已经尝试了很多其他模式,但这对阅读来说是最自然、最直观的
糟糕的是:
import config from '../config'
产生未定义的结果,其中export default buildConfig()
- 将导出更改为简单的
export default basicValues
,可以按预期为我们提供配置对象(但显然没有填充异步值(
我到底做错了什么?
很高兴提供更多的deets作为必要的
提前感谢
请记住,我想导出一个对象,而该对象是异步函数的结果,而不是导出异步函数定义本身
这是不可能的。由于该值是异步检索的,所有使用该值的模块都必须首先等待异步操作完成——这将需要导出一个解析为所需值的Promise。
在Node的新版本中,您可以导入Promise并使用顶级await
来等待它被填充:
import buildConfigProm from '../config';
const config = await buildConfigProm;
如果您不在Node中,则不支持顶级await
。你可以在Promise上调用.then
,只要它被导入:
buildConfigProm.then((config) => {
// put all the module's code in here
});
如果你不喜欢,唯一真正的选择就是使用依赖注入。让您的模块导出以config
为参数的函数,例如:
// useConfig.ts
export default (config: Config) => {
console.log('color2', config.color2);
};
这样,唯一需要异步的就是入口点,它等待Promise解析,然后用它调用所需的模块:
// index.ts
import buildConfigProm from './config';
import useConfig from './useConfig';
buildConfigProm
.then((config) => {
useConfig(config);
})
.catch(handleErrors);