I'm trying to reduce the amount of times the database object is initialized in my data access file (variable database
inside the file tree-rxdb.mjs
). I created a global variable to hold a reference to the database object and check if it has been initialized before, if it has I just return the variable to the caller without initializing it again. For some reason, the database
it's always undefined every time I call this function, even after I have successfully written to the database using the same code. Weirdly, the same doesn't happen to the dao
variable inside tree.mjs
even though I believe I'm giving it the same treatment but obviously getting differing results. I'm just emulating this code but for some reason it's not working out for the database
variable inside tree-rxdb.mjs
, what am I not seeing?
tree-rxdb.mjs
import RxDB from 'rxdb';
import adapter from 'pouchdb-adapter-leveldb'
import leveldown from 'leveldown'
import Log from '../utils/log.mjs';
const TAG = 'fruits-rxdb'
RxDB.plugin(adapter)
var database;
const treeSchema = {
title: 'fruits schema',
description: 'Describes a fruits tree',
version: 0,
type: 'object',
properties: {
name: { type: 'string' },
desc: { type: 'string' },
url: { type: 'string' },
state: {
type: 'integer',
enum: [0, 1]
},
favorite: {
type: 'boolean'
},
dateAdded: { type: 'string' },
userId: { type: 'string' }
}
}
async function connectDB() {
Log.debug(`Database object = ${database}`, TAG)
if (database) return database;
database = await RxDB.create({
name: 'fruitsdb',
adapter: leveldown,
password: (process.env.DB_PASSWORD || 'myfruitsJsPasswordTemp')
});
await database.collection({
name: 'trees',
schema: treeSchema
});
Log.debug('Database has been initialized', TAG)
return database;
}
export async function create(tree) {
const db = await connectDB();
db.trees.insert(tree.JSON);
}
tree.mjs
import util from 'util'
import logger from '../utils/log.mjs'
import Fruit from './Fruit.mjs'
const TAG = "tree-dao"
var dao;
async function model() {
logger.debug(`DAO object = ${util.inspect(dao)}`, TAG)
if(dao) return dao;
dao = await import(`../dao/tree-${process.env.MODEL}`);
logger.debug(`DAO model has been initialized: ${util.inspect(dao)}`, TAG);
return dao;
}
export async function add(){
const Fruit = new Fruit(undefined, 'Peach', 'peach 123',
'http://something.com', 0, false, new Date().toISOString(), 'admin');
(await model()).create(Fruit);
}
app.mjs
import express from 'express';
import logger from 'morgan';
import cookieParser from 'cookie-parser';
import bodyParser from 'body-parser';
import { default as fruits } from "./routes/fruits"
import * as tree from './models/tree.mjs'
const app = express();
app.use(logger("dev"));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use("/fruits", fruits);
const add = async () => {
await tree.add();
await tree.add();
await tree.add();
};
add();
export default app
The problem is that database is only written when the promise of the creation is resolved. So calling connectDB multiple times will have database === undefined each time.
You should cache the creation-promise and return that from connectDB if it already exists.
Instead of
if (database) return database;
database = await RxDB.create({
name: 'fruitsdb',
adapter: leveldown,
password: (process.env.DB_PASSWORD || 'myfruitsJsPasswordTemp')
});
do
if (database) return await database;
database = RxDB.create({
name: 'fruitsdb',
adapter: leveldown,
password: (process.env.DB_PASSWORD || 'myfruitsJsPasswordTemp')
});
I was missing an await
in tree.mjs
. The line (await model()).create(Fruit);
should be await (await model()).create(Fruit);
the inner await
was throwing me off. Now it's behaving like I expected it to.
In Node.js global scope is equal to the files' own scope. If you want to define a global variable accesible by all files at runtime, useglobal
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.