2010-07-06 74 views
0

我正在使用Google Chrome扩展程序。在弹出的我有以下代码:现在Google Chrome JavaScript数组错误?

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

,我会假设,第一个命令将发行书签我的#。事实上,当我使用Chrome的调试器并将bookmarks.length添加到监视列表中时,值是418。在调试器的控制台中,我可以编写bookmarks.length,它会给我正确的长度。我可以键入

for(x = 0; x < bookmarks.length; x++){ console.debug(bookmarks[x]); } 

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

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

for(x = 0; x < 10; x++){ 
    bookmarks.push(x); 
} 

然后bookmarks.length将是10日,再428还当我添加以下功能:

function printlen(){ 
    console.debug(bookmarks.length); 
} 

,然后,如果我补充身体

<a href="#" onclick="printlen()">test</a> 

然后我会还得到正确的bookmarks.length值。

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

+2

请不要忘了'var'来声明局部变量(如上面的“X”)! ! – Pointy 2010-07-06 23:15:13

+1

如果你正在做铬扩展检查http://area51.stackexchange.com/proposals/10910/google-chrome-extensions-webstore?referrer=SDGU8262nOKdp17Pr161Vw2 – Lizard 2010-07-08 14:16:30

回答

9

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

所以,如果你调用getallbookmarks()后立即看一下bookmarks.length,自然会是不完整的。当您稍后点击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 
+0

所以这里有另一个问题 - 我如何“等待”,直到它完成加载一切? – 2010-07-07 03:26:00

+0

@WayneWerner:补充。 – bobince 2010-07-07 09:07:15