Google Chrome javascript数组错误?

Way*_*ner 0 javascript debugging google-chrome-extension

我正在开发Google Chrome扩展程序.在弹出窗口中,我有以下代码:

var bookmarks = [];
function appendBMTnode(node){
    bookmarks.push([node[0].title, node[0].id]);
}
function addchildren(results){
    for(x = 0; x < results.length; x++){
        bookmarks.push([results[x].title, results[x].id]);
        chrome.bookmarks.getChildren(results[x].id, addchildren);
    }
}
function getallbookmarks(){
    chrome.bookmarks.get('0', appendBMTnode);
    chrome.bookmarks.getChildren('0', addchildren);
}
getallbookmarks();
console.debug(bookmarks.length);
console.debug(bookmarks);
Run Code Online (Sandbox Code Playgroud)

现在,我假设第一个命令会发出我的书签数量.实际上,当我使用Chrome的调试器并将bookmarks.length添加到监视列表时,值为418.在调试器的控制台中,我可以编写bookmarks.length,它会给我正确的长度.我可以打字

for(x = 0; x < bookmarks.length; x++){ console.debug(bookmarks[x]); }
Run Code Online (Sandbox Code Playgroud)

我得到每个内部数组的字符串表示.但是,该原始console.debug(bookmarks.length)输出为零.如果我添加console.debug(bookmarks[0]);到popup.html它告诉我该值未定义.

但是,如果我添加以下内容getallbookmarks()(第一个或最后一个):

for(x = 0; x < 10; x++){
    bookmarks.push(x);
}
Run Code Online (Sandbox Code Playgroud)

然后bookmarks.length首先是10,然后是428.此外,当我添加以下函数时:

function printlen(){
    console.debug(bookmarks.length);
}
Run Code Online (Sandbox Code Playgroud)

如果我补充,然后在体内

<a href="#" onclick="printlen()">test</a>
Run Code Online (Sandbox Code Playgroud)

然后我也会得到正确的bookmarks.length价值.

任何线索为什么书签对象不会注册?

bob*_*nce 9

chrome.bookmarks.get是一个异步函数.当你调用它时,它会立即返回,在后台加载书签数据.

因此,如果您在bookmarks.length通话结束后立即查看getallbookmarks(),它自然会不完整.当您稍后单击按钮时printlen(),书签加载将在此时完成,并且数组将被填充.

你可以不知道你的bookmarks阵列是完成并准备使用,直到两个appendBMTnode()addchildren()已被调用.这就是为什么这些chrome.bookmark方法采用回调函数而不是只返回一个值.

[编辑]:

如何"等待"直到它完成加载所有内容?

实际上,JavaScript并没有为您提供语言级工具(如线程或协同例程)来同步运行异步代码,反之亦然.您将不得不习惯于基于回调函数编写异步代码.

在这种情况下,你可以有你增加你每次称为柜台get()getChildren(),并在每个月底减少appendBMTnodeaddchildren回调.如果计数器在该点达到零,则没有异步调用等待,因此您可以调用自己的"完成"回调函数.回调函数通常被编写为内联函数表达式,以使流更清晰.

目前代码的一个问题是书签数组没有固有的顺序,因为所有内容都是并行调用的.它不保证get()会在之前返回结果getChildren(),并且每次再次addchildren调用getChildren()时,不同父母的结果可以以任何顺序进入.

请考虑使用该getTree()方法.这将一次性为您提供整个书签列表,这可能会更容易处理:

var bookmarks= [];
chrome.bookmarks.getTree(function(marks) {
    for (var i= 0; i<marks.length; i++)
        bookmarks.push([marks[i].title, marks[i].id]);
    // bookmarks is now populated. do code that relies on bookmarks here
});
// at this point bookmarks will still be empty, the callback function hasn't
// happened yet
Run Code Online (Sandbox Code Playgroud)