如何使这个全局变量在调用之间保持其值?
How to make this global variable hold its value between calls?
我正在尝试减少在我的数据访问文件(文件 tree-rxdb.mjs
内的变量 database
)中初始化数据库对象的次数。我创建了一个全局变量来保存对数据库对象的引用,并检查它之前是否已经初始化,如果已经初始化,我只是 return 变量给调用者而不再次初始化它。出于某种原因,每次我调用此函数时 database
它总是未定义,即使在我使用相同的代码成功写入数据库之后也是如此。奇怪的是,tree.mjs
中的 dao
变量并没有发生同样的情况,尽管我相信我给予它相同的处理但显然得到不同的结果。我只是在模拟 this code,但由于某种原因,tree-rxdb.mjs
中的 database
变量无法正常工作,我没看到什么?
树-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
在 Node.js 中,全局范围等于文件自身的范围。如果你想定义一个运行时所有文件都可以访问的全局变量,使用global
问题是只有当创建的承诺被解决时,数据库才会被写入。所以多次调用 connectDB 每次都会有 database === undefined.
您应该缓存来自 connectDB 的创建承诺和 return 如果它已经存在。
而不是
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')
});
我在 tree.mjs
中遗漏了一个 await
。 (await model()).create(Fruit);
行应该是 await (await model()).create(Fruit);
里面的 await
让我失望了。现在它的表现就像我预期的那样。
我正在尝试减少在我的数据访问文件(文件 tree-rxdb.mjs
内的变量 database
)中初始化数据库对象的次数。我创建了一个全局变量来保存对数据库对象的引用,并检查它之前是否已经初始化,如果已经初始化,我只是 return 变量给调用者而不再次初始化它。出于某种原因,每次我调用此函数时 database
它总是未定义,即使在我使用相同的代码成功写入数据库之后也是如此。奇怪的是,tree.mjs
中的 dao
变量并没有发生同样的情况,尽管我相信我给予它相同的处理但显然得到不同的结果。我只是在模拟 this code,但由于某种原因,tree-rxdb.mjs
中的 database
变量无法正常工作,我没看到什么?
树-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
在 Node.js 中,全局范围等于文件自身的范围。如果你想定义一个运行时所有文件都可以访问的全局变量,使用global
问题是只有当创建的承诺被解决时,数据库才会被写入。所以多次调用 connectDB 每次都会有 database === undefined.
您应该缓存来自 connectDB 的创建承诺和 return 如果它已经存在。
而不是
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')
});
我在 tree.mjs
中遗漏了一个 await
。 (await model()).create(Fruit);
行应该是 await (await model()).create(Fruit);
里面的 await
让我失望了。现在它的表现就像我预期的那样。