2017-05-25 82 views
0

背景Chrome擴展不會盡管數組的長度等於1個

開發一個瀏覽器擴展程序(在Mac OS上運行塞拉利昂最新的Chrome),我不能工作了for..of循環進入如何循環通過一個也在運行時動態構建的數組。

請原諒我,如果我失去了一些真正明顯的東西,但我不能爲我的生活找出爲什麼這for..of循環沒有被輸入。

我也嘗試過for..in和循環結構的好老經典,即for (let i = 0; i < array.length; i++) - 不管循環的風格如何,儘管我的數組在運行時報表中有一個單獨的項,但是永遠不會輸入這個塊。

問題代碼和語句

這段代碼獲得一個目錄和切片內的所有文件了最後3個字符(除去.js文件):

const getDirectoryContents = (path) => { 
    let fileNames = [] 

    chrome.runtime.getPackageDirectoryEntry((directoryEntry) => { 
    directoryEntry.getDirectory(path, {}, (subDirectoryEntry) => { 
     const subDirectoryReader = subDirectoryEntry.createReader() 
     subDirectoryReader.readEntries((entries) => { 
     for (const entry of entries) { 
      fileNames.push(entry.name.slice(0, -3)) 
     } 
     }) 
    }) 
    }) 

    return fileNames 
} 

chrome.runtime.onStartup()回調函數裏面我們想要添加一些上下文菜單,我們這樣做:

const addContextMenus =() => { 
    console.log(getDirectoryContents('commands')) 
    for (const command of getDirectoryContents('commands')) { 
    const properties = { 
     id: command, 
     title: command, 
     contexts: ['editable'] 
    } 
    chrome.contextMenus.create(properties) 
    console.log(`Created context menu ${properties.title}`) 
    } 
    console.log('End addContextMenus') 
} 

現在,在運行時,上述代碼將輸出此背景頁控制檯中:

Console log screenshot

但是我們可以看到(由於缺乏控制檯日誌的「創建上下文菜單...」 - 永遠不會進入循環,儘管數組的長度爲1.

我在Chrome開發人員文檔中沒有發現任何內容,表明getDirectoryContents是異步的 - 這可能是一種可能的解釋 - 但只是爲了確保我甚至嘗試添加回調param指向getDirectoryContents函數,以確保在數組填充後我們正在循環。

編輯:仔細檢查原始函數之後,很明顯數組實際上是在返回之前有機會由目錄讀取器填充的。下面回答。

同樣的結果!

任何幫助將不勝感激。謝謝你的時間。

+1

你有一個典型的異步問題(返回空數組回調完成之前)。不要僅僅對混合使用回調,使用調試斷點跟蹤代碼並研究異步指南。 –

+1

[我如何從異步調用返回響應?](https:// stackoverflow。com/questions/14220321/how-do-i-return-the-an-asynchronous-call) –

+0

控制檯輸出提示這可能不是異步問題 - 第一行輸出一個長度爲1的數組該函數的結尾輸出「End addContextMenus。此外,我通過添加一個回調函數來嘗試這種方式,我將用回調函數發佈代碼,以便您可以看到我是如何做到的。 – GrayedFox

回答

0

多麼尷尬!傳入一個回調函數並在正確的時間執行它解決了它。評論都是正確的 - 典型的異步問題 - 感謝您的支持。

問題出在原始函數的第15行上:我在返回數組之前有機會進行填充。

工作職能:

const getDirectoryContents = (path, callback) => { 
    chrome.runtime.getPackageDirectoryEntry((directoryEntry) => { 
    directoryEntry.getDirectory(path, {}, (subDirectoryEntry) => { 
     const subDirectoryReader = subDirectoryEntry.createReader() 
     let fileNames = [] 

     subDirectoryReader.readEntries((entries) => { 
     for (const entry of entries) { 
      fileNames.push(entry.name.slice(0, -3)) 
     } 

     callback(fileNames) 
     }) 
    }) 
    }) 
}