Mozilla WebExtension API storage - Debugging with and without breakpoints leads to different output

杀马特。学长 韩版系。学妹 提交于 2020-01-13 05:53:28

问题



Hello guys,
i am trying to implement an add-on for the Mozilla-Firefox Browser. The following script shows one backgorund script I already successfully integrated. It uses the Mozilla WebExtension API storage. It gets executed but the log on the browser console suprises me. I get alternating logged nothing and:

bla
bla
bla

If and only if I set breakpoints on significant lines (especially the last 5 lines) of my code in Debugging-Mode I get always the expected result:

bla

How is it that the output depends on setting breakpoints. I have no idea what is happening and can not find any similar problems on the internet. Can somebody explain to me what is happening and what I can do to prevent the wrong output?

storeManager.js:

var localStore = chrome.storage.local;  
var StoreManager = function(){};

StoreManager.prototype.addItem = function(type, item){
    var thisRef = this;

    localStore.get(type, 
        function(obj){
            if(chrome.runtime.lasterror){
                console.log(chrome.runtime.lastError);
            }else{
                var oldArr = obj[type];

                if(oldArr === undefined)
                    oldArr = [];

                if(oldArr.indexOf(item) !== -1)
                    return;

                oldArr.push(item);
                thisRef.setItem(type, oldArr);
            }
        }
    );
}

StoreManager.prototype.removeItem = function(type, item){
    var thisRef = this;

    localStore.get(type, 
        function(obj){
            if(chrome.runtime.lasterror){
                console.log(chrome.runtime.lastError);
            }else{
                var oldArr = obj[type];

                if(oldArr === undefined)
                    return;

                var index = oldArr.indexOf(item);
                if(index === -1)
                    return;

                oldArr.splice(index, 1);
                thisRef.setItem(type, oldArr);
            }   
        }
    );
}

StoreManager.prototype.setItem = function(type, item){
    localStore.set({ [type] : item }, 
        function(){
            if(chrome.runtime.lasterror){
                console.log(chrome.runtime.lastError);
            }
        }
    );
}

StoreManager.prototype.visitItems = function(type, visit){
    localStore.get(type, 
        function(obj){
            if(chrome.runtime.lasterror){
                console.log(chrome.runtime.lastError);
            }else{
                var oldArr = obj[type];

                if(oldArr !== undefined){
                    for(var i=0; i<oldArr.length; i++){
                        visit(oldArr[i]);
                    }
                }
            }
        }
    );
}

function justLog(str){
    console.log(str);
}

var sm = new StoreManager();
sm.visitItems("lol", justLog);
sm.addItem("lol", "bla");
sm.visitItems("lol", justLog);
sm.removeItem("lol", "bla");
sm.visitItems("lol", justLog);


manifest.json:

{
    "manifest_version": 2,
    "name": "Addon",
    "version": "0.0",

    "description": "no desc",

    "background": {
        "scripts": [
            "storeManager.js"
        ]
    },

    "permissions": [
        "storage"
    ]
}

回答1:


storage.local.set() is asynchronous. The data isn't guaranteed to be visible to a call to get() until the callback is invoked (or if you use browser.storage.local, set() will return a Promise and the data will be guaranteed to be written when that Promise resolves).

Your code is inherently full of race conditions. The calls to addItem() and removeItem() are racing against the calls to visitItems(), by setting breakpoints you let one path or the other "win" the race.

If you expect deterministic results, I would suggest using the Promise variants of storage.local and writing your code as a series of chained handlers.



来源:https://stackoverflow.com/questions/38814120/mozilla-webextension-api-storage-debugging-with-and-without-breakpoints-leads

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!