我道歉,如果我的问题听起来很愚蠢,但我发现在很多情况下我需要全局变量,例如代表数据库和redis客户端的变量,在许多文件中使用,但是这些变量本身需要等待从中获取它们的值承诺或异步函数,用于初始化与数据库或redis服务器的通信。
我想做那样的事情
init.js:
export default async () => {
return await initializeWhatever()
}
db.js:
import init from './init'
let db = null
init().then(val => db = val)
export default db
api.js:
import db from './db'
const doApi = req => {
db('users').select({username:req.param.username})
}
但db
中导入的api.js
变量始终为null,为什么init()
完成时它不会更新为正确的值?如果我使用db的方法是错误的,那么导出异步计算的全局变量的正确方法是什么?
答案 0 :(得分:2)
导出变量时,您要导出存储在变量中的内容,而不是变量本身。分配给变量只会更改变量,但不会影响导出的内容。
这样想:
let a = null;
let b = a;
a = 'something';
console.log(b);
// null
请注意,在a
中存储新内容并不会改变b
中存储的内容。
要在问题中执行类似的操作,您需要导出对象并更新该对象的引用:
<强> init.js 强>
export default async () => {
return await initializeWhatever()
}
<强> DB-module.js 强>
import init from './init'
const dbModule = { db: null };
init().then(val => dbModule.db = val)
export default dbModule
<强> api.js 强>
import dbModule from './db-module'
const doApi = req => {
dbModule.db.select({username:req.param.username})
}
显然,您可能希望更改某些名称以使事情更清晰。我对你的项目了解不多,所以我不确定如何命名。
此外,您必须确保有一些方法可以确保{/ 1}}对象在实际到位之后发生任何使用。换句话说,您必须确保在dbModule.db
doApi
完成api.js
之前,init
无法调用db-module.js
。
要执行此操作,您需要建立从init
到api.js
的承诺链:
<强> init.js 强>
export default async () => {
return await initializeWhatever()
}
<强> DB-module.js 强>
import init from './init'
const dbModule = { db: null };
dbModule.promise = init().then(val => dbModule.db = val)
export default dbModule
<强> api.js 强>
import dbModule from './db-module'
const doApi = req => {
dbModule.db.select({username:req.param.username})
}
dbModule.promise.then(() => {
// Set up routes and start listening in this promise chain.
// Ensure there is no way `doApi` can be called before this happens.
});
为什么这样做?因为在JS中,变量不存储对象的整个副本。他们只是存储references。如果两个变量指向同一个对象,则无论您是通过一个变量还是另一个变量访问它,都会反映对该对象的更改。可以这样想:
let c = { prop: null };
let d = c;
c.prop = 'something';
console.log(d.prop);
// 'something'
答案 1 :(得分:0)
你可以做一个吸气剂。
的一些事情export default function getDB() {
return db;
}