最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to export a variable that takes its value from an async function - Stack Overflow

programmeradmin4浏览0评论

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 munication to the database or redis servers.

I want to do something like that

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

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 puted asynchronously?

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 munication to the database or redis servers.

I want to do something like that

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

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 puted asynchronously?

Share Improve this question edited Apr 12, 2018 at 14:11 ibrahim mahrir 31.7k5 gold badges49 silver badges77 bronze badges asked Apr 12, 2018 at 13:57 Ejonas GGggEjonas GGgg 4762 gold badges7 silver badges19 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 10

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.

Think of it like this:

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

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.

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.

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

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'

You can make a getter. Something about

export default function getDB() {
  return db;
}
发布评论

评论列表(0)

  1. 暂无评论