谷歌浏览器扩展中的变量值不一致

时间:2011-03-06 22:43:04

标签: javascript google-chrome-extension global-variables anonymous-function bookmarks

我正在为Chrome编写扩展程序,基本上可以使用书签。 以下代码位于弹出式html文件中,并且正在on body事件中调用bookmarkHelper()函数。它应该检查是否存在名为“TestFolder”的书签文件夹。如果存在,则删除文件夹中的所有书签。如果没有,则创建空文件夹。

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': 'TestFolder'},
                        function(newFolder) {} );
    });

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

现在我的问题是,当文件夹中有书签时,它不会删除它们。但是,如果我将最后3行更改为

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

删除书签。 在另一种情况下,当我检查弹出窗口时,它会使用原始代码删除书签。这很奇怪,我不知道该怎么做。 我在这里错过了一些匿名函数线程类型的概念吗?因为AFAIK,JS是单线程的。

2 个答案:

答案 0 :(得分:2)

Chrome API调用是异步的,因此如果您想按顺序运行它们,则需要将代码置于回调中。此外,您还应以异步方式重写整个bookmarkHelper,假设您想在继续之前等待创建书签文件夹。

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
});

我重新创建它以总是删除整个树并重新创建它,否则你需要监视整个chrome.bookmarks.remove回调是否完成并行执行以便继续,这是令人讨厌的。

答案 1 :(得分:1)

正确,JavaScript是单线程的,但是它经常使用'回调',当特定函数完成它的操作时,它会运行,同时允许以下代码行继续运行。

您在chrome.bookmarks.getTree()传递的功能不会马上执行;相反,它会在chrome.bookmarks.getTree完成其工作后运行,然后传递结果。与此同时,没有等待,所以下面的代码会马上执行。

将最后三行移动到传递给chrome.bookmarks.getTree的函数中,您可能会得到更明智的结果。