首页 > 解决方案 > 如何让这个全局变量在调用之间保持它的值?

问题描述

我正在尝试减少在我的数据访问文件(文件database内的变量tree-rxdb.mjs)中初始化数据库对象的次数。我创建了一个全局变量来保存对数据库对象的引用,并检查它之前是否已初始化,如果已经初始化,我只是将变量返回给调用者而不再次初始化它。出于某种原因,database每次调用此函数时它总是未定义,即使在我使用相同的代码成功写入数据库之后也是如此。奇怪的是,即使我相信我给予它相同的处理但显然得到不同的结果,dao内部变量也不会发生同样的情况。tree.mjs我只是在模拟这段代码,但由于某种原因,它不适用于database里面的变量tree-rxdb.mjs,我没看到什么?

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

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

应用程序.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

标签: node.jsrxdb

解决方案


问题是只有在解决了创建的承诺时才写入数据库。所以多次调用 connectDB 每次都会有 database === undefined 。

如果它已经存在,您应该缓存创建承诺并从 connectDB 中返回。

代替

if (database) return database;
database = await RxDB.create({
    name: 'fruitsdb',
    adapter: leveldown,
    password: (process.env.DB_PASSWORD || 'myfruitsJsPasswordTemp')
});

if (database) return await database;
database = RxDB.create({
    name: 'fruitsdb',
    adapter: leveldown,
    password: (process.env.DB_PASSWORD || 'myfruitsJsPasswordTemp')
});

推荐阅读