递归JavaScript函数在返回后继续运行

时间:2020-09-03 19:05:12

标签: javascript recursion frontend callstack web-frontend

我正在尝试创建一个JavaScript函数,该函数以递归方式搜索文件结构中的文件/目录,并在找到该文件时返回该文件。这是文件结构的示例:

var fileStructure = [
  {'pictures': ['picture1.png', {'beach': ['picture2.png']}]},
  {'videos': ['video1.mov', 'video2.mov']}
]

在词典中,键代表目录的名称,而值代表目录的内容。数组中的每个项目都是文件。因此,如果我打电话给findFile('picture1.png'),我应该成为现实;或者,如果我打电话给findFile('videos'),我也应该成为真实。这是我到目前为止的内容:

var fileStructure = [{ "music": [{ "acoustic": ["vlad-gluschenko-stars-extended.mp3"] }, { "chinese": ["AlbumArtSmall.jpg", "Folder.jpg", "keys-of-moon-yugen.mp3"] }, { "lofi": ["le-gang-relax-man.mp3", "purple-cat-field-of-fireflies.mp3"] }] }, { "sounds": [{ "campfire": ["fire-crackle.mp3", "fire-rumble.mp3"] }, { "rain": ["rain-heavy.mp3", "rain-light.mp3", "rain-tapping.mp3"] }, { "thunderstorm": ["thunderstorm.mp3"] }, { "wind": ["wind-base.mp3", "wind-howling.mp3", "wind-rattling.mp3"] }] }]

function findFile(fileName, dir) {
    for (i in dir) {
        let entry = dir[i];

        // If entry is a dictionary, unpack into array
        if (entry.constructor == Object) {
            // If the file being searched for is itself a directory
            if (Object.keys(entry).indexOf(fileName) != -1) {
                // !!!!! THIS PRINTS BUT THE FUNCTION KEEPS RUNNING !!!!!
                console.log(`Found directory: ${fileName}`);
                return true;
            }
            entry = Object.values(entry);
        }

        // If entry is an array (meaning it is the contents of a directory)
        if (Array.isArray(entry)) {
            findFile(fileName, entry);
        }
        // Found file
        else if (entry == fileName) {
            return true;
        }
    }
    return false;
}

// 
fileExists = findFile('tets', fileStructure);
console.log("done", fileExists);

fileExists = findFile('lofi', fileStructure);
console.log("done", fileExists);

在我的代码中,我这样调用该函数:fileExists = findFile('lofi', audioLibrary);如果您在注释中用感叹号包围,则该行将按预期方式打印,但是即使返回true后,该函数仍会继续运行,最终, fileExists变量的计算结果为false。

为什么即使返回后循环仍会继续?

This是我在返回行中添加断点时发生的情况。如您所见,循环再次运行。

编辑: 添加了我正在使用的文件结构。

1 个答案:

答案 0 :(得分:0)

问题是我实际上没有返回findFile(fileName, entry);,所以该函数将仅搜索一个目录,并且没有实际的递归(哈哈!)为了解决这个问题,我跟踪了所有子目录在当前目录中使用变量directories搜索。然后,一旦检查了要搜索的目录中的最后一个文件,如果没有找到结果,它将尝试搜索directories数组中的每个目录。如果它设法在任何目录中找到匹配项,则该函数将返回true。

fileStructure = [{ "music": [{ "acoustic": ["vlad-gluschenko-stars-extended.mp3"] }, { "chinese": ["AlbumArtSmall.jpg", "Folder.jpg", "keys-of-moon-yugen.mp3"] }, { "lofi": ["le-gang-relax-man.mp3", "purple-cat-field-of-fireflies.mp3"] }] }, { "sounds": [{ "campfire": ["fire-crackle.mp3", "fire-rumble.mp3"] }, { "rain": ["rain-heavy.mp3", "rain-light.mp3", "rain-tapping.mp3"] }, { "thunderstorm": ["thunderstorm.mp3"] }, { "wind": ["wind-base.mp3", "wind-howling.mp3", "wind-rattling.mp3"] }] }]

function findFile(fileName, dir) {
    var directories = [];
    for (i in dir) {
        let entry = dir[i];

        // If entry is a dictionary, unpack into array
        if (entry.constructor == Object) {
            // If the file being searched for is itself a directory, then search the dictionary for a directory with the name of fileName
            if (Object.keys(entry).indexOf(fileName) != -1) {
                return true;
            }
            entry = Object.values(entry);
        }

        // If entry is an array (meaning it is the inside of a directory)
        if (Array.isArray(entry)) {
            directories.push(entry);
        }
        else if (entry == fileName) {
            console.log('Found the file:');
            console.log(entry);
            return entry;
        }

        // If item is the last item in directory and no files have matched, begin to search each of the sub-directories
        if (i == dir.length - 1) {
            for (directory of directories) {
                if (findFile(fileName, directory)) {
                    return true;
                }
            }
        }
    }
    return false;
}

fileExists = findFile('foo', fileStructure);
console.log('done', fileExists);

fileExists = findFile('lofi', fileStructure);
console.log('done', fileExists);