单个实例中的变量 class 没有改变
Variable in single instance class is not changing
我理解带有此类标题的问题通常会被否决,但我想不出如何表达得好。
我有一个 class 需要在整个应用程序中只有一个实例。我了解到这(我认为)被称为单身人士,但我没有这样设置。我的方式是:
import _Storage from '../components/storage/Storage'
export const Storage = new _Storage();
然后我可以在任何文件中导入 Storage
,它们都将使用相同的实例。
_Storage
class 看起来像这样:
class _Storage {
isReady: boolean;
constructor() {
this.isReady = false;
}
initialise() {
document.addEventListener('deviceready', this.onReady);
}
onReady() {
this.isReady = true;
File.checkDir(File.dataDirectory, "data").catch(
() => {
File.createDir(File.dataDirectory, "data", true);
}
);
File.listDir(File.dataDirectory, "data").then(
(succ) => {
if (succ.length === 0) {
File.createFile(File.dataDirectory+"data", "data.txt", false);
}
}
);
}
async write(data, key?) {
if (!this.isReady) return;
let r = await this.read();
let d = isEqual(r, {}) ? r : JSON.parse(r)
if (isEqual(d, {})) {
d["info"] = data;
}
else {
d.info[key ? key : d[0]] = data;
}
await File.writeExistingFile(File.dataDirectory+"data", "data.txt", JSON.stringify(d));
}
async read(key?) {
if (!this.isReady) return;
let d = JSON.parse(await File.readAsText(File.dataDirectory+"data", "data.txt"));
if (key) {
return d.info[key];
}
return d;
}
}
export default _Storage;
在我的 App.tsx 文件中,我调用 Storage.initialise
,一旦准备好,调用 onReady
。这应该将 isReady
变量更新为 true,并且对于某些 console.log,确实如此。但是,如果我稍后调用 read
或 write
,它只会在第一行显示 return,因为 isReady
恢复为默认值 false。当然,如果 class 只有一个实例并且 isReady
被更改,无论我何时何地调用函数 isReady
应该仍然是它之前设置的(那将是true
)。我通过从构造函数中打印一些东西来仔细检查它只是一个 class 并且果然,它只被实例化一次所以为什么 isReady
不保持真实?
我也试过像单例一样设置它:
import _Storage from '../components/storage/Storage'
var StorageSingleton = (function () {
var instance;
function createInstance() {
var inst = new _Storage();
return inst;
}
return {
getInstance: function () {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
export const Storage = StorageSingleton;
但问题仍然存在。我在这里错过了什么?
编辑:这是一个示例,希望能突出更多问题:
文件 1
///File 1
class Foo {
baz: boolean;
constructor() {
this.baz = false;
}
setBaz() {
this.baz = true;
}
getBaz() {
return this.baz
}
}
export default Foo;
文件 2
///File 2
import Foo from "./File1"
export const Bar = new Foo();
文件 3
///File 3
import { Bar } from './File2'
//console.log(Bar.baz) :> false
Bar.setBaz()
//console.log(Bar.baz) :> true
文件 4
///File 4
import { Bar } from './File2'
//console.log(Bar.baz) :> false
console.log(Bar.getBaz()) //:> false
//File 4 and File 3 have the same instance of 'Bar' so why is 'baz' now false if it was set to true in file 3?
这里不需要 class。
考虑改用模块。
您将导出模块中的函数:
let ready = false;
export function initialise() {
// ...
}
export onReady() {
// ...
}
export async write(data, key?) {
// ...
}
export async read(key?) {
// ...
}
本例中ready将无法访问,如果要访问可以导出。
然后你可以这样导入你的模块:
import * as Storage from "path_to_storage";
并这样调用函数:
Storage.write(/* params */);
Storage.read(/* params */);
// etc
或者您可以导入一些特定的函数(这会给您带来灵活性):
import { initialise as initialiseStorage, read as readStorage } from "path_to_storage";
然后使用它们:
initialiseStorage();
readStorage();
我理解带有此类标题的问题通常会被否决,但我想不出如何表达得好。
我有一个 class 需要在整个应用程序中只有一个实例。我了解到这(我认为)被称为单身人士,但我没有这样设置。我的方式是:
import _Storage from '../components/storage/Storage'
export const Storage = new _Storage();
然后我可以在任何文件中导入 Storage
,它们都将使用相同的实例。
_Storage
class 看起来像这样:
class _Storage {
isReady: boolean;
constructor() {
this.isReady = false;
}
initialise() {
document.addEventListener('deviceready', this.onReady);
}
onReady() {
this.isReady = true;
File.checkDir(File.dataDirectory, "data").catch(
() => {
File.createDir(File.dataDirectory, "data", true);
}
);
File.listDir(File.dataDirectory, "data").then(
(succ) => {
if (succ.length === 0) {
File.createFile(File.dataDirectory+"data", "data.txt", false);
}
}
);
}
async write(data, key?) {
if (!this.isReady) return;
let r = await this.read();
let d = isEqual(r, {}) ? r : JSON.parse(r)
if (isEqual(d, {})) {
d["info"] = data;
}
else {
d.info[key ? key : d[0]] = data;
}
await File.writeExistingFile(File.dataDirectory+"data", "data.txt", JSON.stringify(d));
}
async read(key?) {
if (!this.isReady) return;
let d = JSON.parse(await File.readAsText(File.dataDirectory+"data", "data.txt"));
if (key) {
return d.info[key];
}
return d;
}
}
export default _Storage;
在我的 App.tsx 文件中,我调用 Storage.initialise
,一旦准备好,调用 onReady
。这应该将 isReady
变量更新为 true,并且对于某些 console.log,确实如此。但是,如果我稍后调用 read
或 write
,它只会在第一行显示 return,因为 isReady
恢复为默认值 false。当然,如果 class 只有一个实例并且 isReady
被更改,无论我何时何地调用函数 isReady
应该仍然是它之前设置的(那将是true
)。我通过从构造函数中打印一些东西来仔细检查它只是一个 class 并且果然,它只被实例化一次所以为什么 isReady
不保持真实?
我也试过像单例一样设置它:
import _Storage from '../components/storage/Storage'
var StorageSingleton = (function () {
var instance;
function createInstance() {
var inst = new _Storage();
return inst;
}
return {
getInstance: function () {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
export const Storage = StorageSingleton;
但问题仍然存在。我在这里错过了什么?
编辑:这是一个示例,希望能突出更多问题:
文件 1
///File 1
class Foo {
baz: boolean;
constructor() {
this.baz = false;
}
setBaz() {
this.baz = true;
}
getBaz() {
return this.baz
}
}
export default Foo;
文件 2
///File 2
import Foo from "./File1"
export const Bar = new Foo();
文件 3
///File 3
import { Bar } from './File2'
//console.log(Bar.baz) :> false
Bar.setBaz()
//console.log(Bar.baz) :> true
文件 4
///File 4
import { Bar } from './File2'
//console.log(Bar.baz) :> false
console.log(Bar.getBaz()) //:> false
//File 4 and File 3 have the same instance of 'Bar' so why is 'baz' now false if it was set to true in file 3?
这里不需要 class。
考虑改用模块。
您将导出模块中的函数:
let ready = false;
export function initialise() {
// ...
}
export onReady() {
// ...
}
export async write(data, key?) {
// ...
}
export async read(key?) {
// ...
}
本例中ready将无法访问,如果要访问可以导出。
然后你可以这样导入你的模块:
import * as Storage from "path_to_storage";
并这样调用函数:
Storage.write(/* params */);
Storage.read(/* params */);
// etc
或者您可以导入一些特定的函数(这会给您带来灵活性):
import { initialise as initialiseStorage, read as readStorage } from "path_to_storage";
然后使用它们:
initialiseStorage();
readStorage();