browser.storage.local 值被覆盖而不是附加到

browser.storage.local value getting overwritten instead of appended to

我正在尝试编写一个异步记录器函数,用于 Firefox Web 扩展,除了控制台输出之外,它还写入记录消息的持久副本。它维护所有以前创建的日志,使用 Date() 字符串命名它们。 (在我开始工作后计划轮换机制)。 运行 时的 Log() 函数应该将消息附加到当前日志并在 browser.storage.local.get(window.logFile) 中反映出来。 但是,只会记录最后一条记录的消息,它会用它覆盖日志。不好意思这里面代码太多了,少了也看不下去了

我试过使函数不是异步的而不是等待它。我发现内部函数work(obj)每次都从它的promise中接收到一个空对象,但我不知道为什么。

function isEmpty(obj) {
    // isEmpty(obj)
    // Checks if an object is empty.
    // EX: var a = {};
    // returns true or false
    if (Object.entries(obj).length === 0) {
        if (obj.constructor === Object) {
            return true;
        }
    }
    return false;
}

async function Log(message, level) {
    // Log(message, level)
    // Primary logging facility for the program
    // Use instead of console.log to allow exportable output
    // Arguments:
    //      message:
    //          A string.
    //      level:
    //          A string. Valid levels are:
    //              "error", "warn", "log", "info", "debug"
    //
    "use strict";
    function work(obj) {
        // Does the actual work, called as onResolve handler for a promise.
        console.log(obj);
        var oldLog;
        var newLog;
        if (!isEmpty(obj)) {
            console.info("Not Empty");
            oldLog = obj[window.logFile];
        } else {
            console.info("empty");
            oldLog = "";
        }

        switch (level) {
            case "error":
                newLog = oldLog + level + ":: " + message + "\n";
                console.error(message);
                browser.storage.local.set({[window.logFile]: newLog});
                break;
            case "warn":
                newLog = oldLog + level + ":: " + message + "\n";
                console.warn(message);
                browser.storage.local.set({[window.logFile]: newLog});
                break;
            case "info":
                newLog = oldLog + level + ":: " + message + "\n";
                console.info(message);
                browser.storage.local.set({[window.logFile]: newLog});
                break;
            case "debug":
                newLog = oldLog + level + ":: " + message + "\n";
                console.debug(message);
                browser.storage.local.set({[window.logFile]: newLog});
                break;
            default:
                newLog = oldLog + level + ":: " + message + "\n";
                console.log(message);
                browser.storage.local.set({[window.logFile]: newLog});
        }
    }


    if (typeof(window.logFile) !== "string") {
        window.logFile = "" + new Date();
        console.log(window.logFile + "\n Program started.");
        let getLogs = browser.storage.local.get("allLogs");
        getLogs.then((obj) => {
            console.log(obj);
            if (!isEmpty(obj)) {
                obj.allLogs.push(window.logFile);
                browser.storage.local.set(obj);
            } else {
                browser.storage.local.set({allLogs: [window.logFile]});
            }
        });
    }

    console.log(window.logFile);
    //browser.storage.local.get(window.logFile).then(work);
    work(await browser.storage.local.get(window.logFile));
}

Log("logger loaded", "debug");
Log("logger should have two messages", "debug");

我希望底部两个调用的输出为 browser.storage.local.get(window.logFile) 生成一个值,其中包含一个带有 "debug:: logger loaded\ndebug:: logger should have two messages"

的字符串

但是实际上只有第二条消息被写入。

抱歉在这里浪费时间,我发现了另一个问题,虽然不是很重复,但几乎可以解释它。基本上,日志函数会 co-exist 创建竞争条件。需要一个队列来管理它,因为日志 运行 同时具有随机输出,因为 browser.storage.local.get 从一个日志在另一个写入其输出之前被调用。