Как заставить эту глобальную переменную хранить свое значение между вызовами? - PullRequest
0 голосов
/ 17 октября 2019

Я пытаюсь уменьшить количество инициализаций объекта базы данных в моем файле доступа к данным (переменная database внутри файла tree-rxdb.mjs). Я создал глобальную переменную для хранения ссылки на объект базы данных и проверки, была ли она инициализирована ранее, если я просто возвращаю переменную вызывающей стороне, не инициализируя ее снова. По какой-то причине database всегда неопределен каждый раз, когда я вызываю эту функцию, даже после того, как я успешно записал в базу данных, используя тот же код. Как ни странно, этого не происходит с переменной dao внутри tree.mjs, хотя я полагаю, что я делаю то же самое, но, очевидно, получаю разные результаты. Я просто эмулирую этот код , но по какой-то причине он не работает для переменной database внутри tree-rxdb.mjs, что я не вижу?

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

Ответы [ 3 ]

0 голосов
/ 17 октября 2019

Проблема в том, что база данных записывается только тогда, когда обещание создания разрешено. Поэтому при многократном вызове connectDB база данных === будет определяться каждый раз.

Вам следует кэшировать обещание создания и вернуть его из 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')
});
0 голосов
/ 20 октября 2019

Мне не хватало await в tree.mjs. Строка (await model()).create(Fruit); должна быть await (await model()).create(Fruit);, внутренняя await отбрасывает меня. Теперь он ведет себя так, как я ожидал.

0 голосов
/ 17 октября 2019

В Node.js глобальная область равна собственной области видимости файлов. Если вы хотите определить глобальную переменную, доступную для всех файлов во время выполнения, используйте global

...