2010-07-06 72 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