2017-05-25 143 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) 
     }) 
    }) 
    }) 
}