1

我理解像这样的标题的问题通常会被否决,但我想不出如何说得好。

我有一个类只需要在整个应用程序中有一个实例。我了解到这(我认为)被称为单例,但我没有以这种方式设置它。我的方式是:

import _Storage from '../components/storage/Storage'

export const Storage = new _Storage();

然后我可以导入Storage任何文件,它们都将使用相同的实例。该类_Storage如下所示:

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,它确实如此。但是,如果我稍后调用reador write,它只会在第一行返回,因为isReady返回到默认值 false。当然,如果只有一个类的实例并且isReady被更改,那么无论我何时何地调用一个函数isReady,它应该仍然是它之前设置的(那将是true)。我通过从构造函数打印一些东西来仔细检查它只是一个类,果然,它只实例化一次,所以为什么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?
4

1 回答 1

2

你不需要在这里上课。

考虑改用模块。

您将在模块中导出函数:

let ready = false;

export function initialise() {
    // ...
}

export onReady() {
    // ...
}

export async write(data, key?) {
    // ...
}

export async read(key?) {
    // ...
}

在此示例中,准备就绪将无法访问,如果您想访问它,可以将其导出。

然后你可以通过这种方式导入你的模块:

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();
于 2020-10-18T14:51:41.190 回答