如何导出从异步函数获取其值的变量 [英] How to export a variable that takes its value from an async function

查看:499
本文介绍了如何导出从异步函数获取其值的变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很抱歉,我的问题听起来很愚蠢,但是我发现我在很多情况下都需要全局变量(例如代表数据库和Redis客户端的全局变量)在许多文件中使用,但是这些变量本身需要等待以从中获取值许诺或异步函数,初始化与数据库或Redis服务器的通信。

I apologize if my question sounds stupid, but I found that I need in many situations global variables such as ones that represent database and redis clients to be used in many files, however these variables themselves need to wait to get their values from promises or async functions that initialize the communication to the database or redis servers.

我想做类似的事情

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})
}

但是在 api.js 中导入的 db 变量始终为空,为什么呢? init()完成时,它是否更新为正确的值?如果我使用db的方法是错误的,那么导出异步计算的全局变量的正确方法是什么?

However the db variable imported in api.js is always null, why doesn't it get updated to the correct value when init() finishes? If my approach to using db is wrong, what is the correct way to export global variables that are computed asynchronously?

推荐答案

导出变量,您导出的是变量中存储的内容,而不是变量本身。分配给变量只会更改变量,而不会影响导出的内容。

When you export a variable, you're exporting what's stored in the variable, not the variable itself. Assigning to the variable will only change the variable, but will not affect what was exported.

这样想:

let a = null;
let b = a;
a = 'something';
console.log(b);
// null

请注意如何在 a <中存储新内容/ code>不会更改 b 中存储的内容。

Note how storing something new in a doesn't change what's stored in b.

要做类似您想要的事情在您的问题中,您需要导出一个对象并更新对该对象的引用:

To do something like what you want in your question, you need to export an object and update references on that object:

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})
}

显然,您可能想要更改一些名称以使内容更整洁。我对您的项目不太了解,所以不知道如何命名。

Obviously you might want to change some names to make things cleaner. I don't know a lot about your project so I'm not sure how to name them.

此外,您还必须确保采用某种方法确保对 dbModule.db 对象的任何使用都在之后发生。换句话说,您必须确保在<$ c之前不能调用 api.js 中的 doApi db-module.js 中的$ c> init 完成。

Also, you'll have to make sure have some way of making sure that any uses of your dbModule.db object happen after it's actually in place. In other words, you have to make sure there's no way doApi in api.js can be invoked before init in db-module.js finishes.

为此,则需要使 init 中的承诺链可用于 api.js

To do this, you'll need to make the promise chain from init available to 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中,变量不会存储对象的完整副本。他们只是存储引用。如果两个变量指向同一个对象,则无论您是通过一个变量还是通过另一个变量访问对象,对对象的更改都会反映出来。像这样:

Why does this work? Because in JS, variables don't store entire copies of objects. They simply store references. If two variables point at the same object, changes to the object will be reflected whether your access it through one variable or another. Think of it like this:

let c = { prop: null };
let d = c;
c.prop = 'something';
console.log(d.prop);
// 'something'

这篇关于如何导出从异步函数获取其值的变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆