开发者

Google Chrome inconsistent variable values in extensions

开发者 https://www.devze.com 2023-02-14 23:41 出处:网络
I\'m writing an extension for Chrome that basically plays around with the bookmarks. The following code is in the popup html file, and the bookmarkHelper() function is being called in the body onload

I'm writing an extension for Chrome that basically plays around with the bookmarks. The following code is in the popup html file, and the bookmarkHelper() function is being called in the body onload event. It's supposed to check if a bookmark folder called "TestFolder" exists. If it exists, it removes all the bookmarks within the folder. If it doesn't, it creates the empty folder.

var rootFolder = undefined;
function bookmarkHelper() {
    // Create TestFolder folder if it doesn't exist
    chrome.bookmarks.getTree(function(tree) {
        otherFolder = tree[0].children[1].children;
        rootFolder = undefined;
        for(i=0; i<otherFolder.length; i++) {
            if(otherFolder[i].title == "TestFolder") {
                rootFolder = otherFolder[i];
                return;
            }
        }
        chrome.bookmarks.create({'parentId': "2",
                         'title': 'TestFol开发者_如何学Goder'},
                        function(newFolder) {} );
    });

    // Remove all bookmarks from the rootFolder
    for (i=0; i<rootFolder.children.length; i++)
        chrome.bookmarks.remove(rootFolder.children[i].id);
}

Now my problem is that when there's bookmarks in the folder, it doesn't remove them. But if I change the last 3 lines to

setTimeout(function(){
    for (i=0; i<rootFolder.children.length; i++)
        chrome.bookmarks.remove(rootFolder.children[i].id);
}, 100);

it deletes the bookmarks. In a separate case, when I inspect the popup, it deletes the bookmarks using the original code. This is very strange, and I didn't know quite what to make of it. Am I missing some anonymous-function-threading type concept here? Because AFAIK, JS is single-threaded.


Chrome API calls are asynchronous, so if you want to run them in order you need to put your code inside callbacks. Moreover your whole bookmarkHelper should also be rewritten in asynchronous way, assuming you want to wait for a bookmark folder to be created before continue.

function bookmarkHelper(callback) {
    // Create TestFolder folder if it doesn't exist
    chrome.bookmarks.getTree(function(tree) {
        otherFolder = tree[0].children[1].children;
        rootFolder = undefined;
        for(i=0; i<otherFolder.length; i++) {
            if(otherFolder[i].title == "TestFolder") {
                rootFolder = otherFolder[i];

                //"return" here wouldn't return from bookmarkHelper as you probably expect
                break;
            }
        }

        //it would be easier to always just recreate TestFolder 
        if(rootFolder == undefined) {
            chrome.bookmarks.create({'parentId': "2", 'title': 'TestFolder'}, callback);
        } else {
            // Remove whole rootFolder subtree
            chrome.bookmarks.removeTree(rootFolder, function() {
                chrome.bookmarks.create({'parentId': "2", 'title': 'TestFolder'}, callback);            
            });
        }
    });


}

//usage
bookmarkHelper(function(testFolder) {
    //do something with testFolder
});

I remade it to always remove the whole tree and recreate it because otherwise you would need to monitor when the whole bunch of chrome.bookmarks.remove callbacks is done executing in parallel in order to continue, which is nasty.


Correct, JavaScript is single-threaded, however it often uses 'callbacks', which which get run when a particular function has finished doing its thing, in the meantime allowing the following lines of code to continue running.

The function you're passing in chrome.bookmarks.getTree() doesn't get executed right away; instead it gets run when chrome.bookmarks.getTree has finished doing its work and then gets passed the results. In the meantime, there's no waiting, so the code beneath gets executed right away.

Move those last three lines into the function that gets passed into chrome.bookmarks.getTree, and you might get some more sensible results.

0

精彩评论

暂无评论...
验证码 换一张
取 消