如何知道你的递归函数已经结束

时间:2018-01-06 21:59:34

标签: javascript json recursion

我有一个遍历所有目录的递归函数,并将bmp文件放在一个JSON数组中,其中键或文件夹以及子数组是每个文件夹的内容(我不知道我是否&#39 ;明确)。例如,这个文件系统:

- data/ |- hello/ |- j.bmp |- t.bmp - ok/ |- c.bmp 会给出这样的东西:

{"data":{
    "hello":{
      "j.bmp":"j.bmp"
    },
    "t.bmp":"t.bmp"
  },
  "ok":{
    "c.bmp":"c.bmp"
  }
}

所以这是我的代码:

function preload(res_dir, nextfunc, errorfunc){
  let images = {}
  let c = document.createElement("CANVAS");

  function travelDir(directory){
    let dirReader = directory.createReader();
    dirReader.readEntries(function(subdirs){
      subdirs.forEach(function(entry){
        if (entry.isDirectory){
          let path = entry.toURL().replace(res_dir.toURL(),"").split("/");
          let a = images;
          for (var i = 0; i < path.length - 2; i++){
            a = a[path[i]];
          }
          a[entry.name] = {};
          travelDir(entry);
        } else if (entry.name.substr(entry.name.length - 4, 4) == ".bmp"){
          loadres(entry);
        }
      });
    }, errorfunc);
  }

  travelDir(res_dir);

  function loadres(file){
    let a = images;
    let path = file.toURL().replace(res_dir.toURL(),"").split("/");
    for (var i = 0; i < path.length - 1; i++){
      a = a[path[i]];
    }
    a[file.name] = file.name;
  }
}

travelDir函数遍历从res_dir开始的所有目录,在它是目录时创建密钥,否则调用loadres,在JSON数组中添加文件名images

这很好用,但我怎么知道这些函数何时通过所有目录? (如果需要,我需要在整个过程结束时执行函数nextfunc,将images作为参数,当它包含整个文件树时)

1 个答案:

答案 0 :(得分:1)

由于您的代码是异步的,因此递归并不易于管理。你不能只从它自己内部调用travelDir,因为父函数只在孩子完成时才完成,而这不是你调用它的那一刻。

如果您的工具链启用了ES7,那么只需使用async/await,即:

async function travelDir(directory) {
    .... await travelDir(subdir)
}

await travelDir(root)
nextfunc()

否则,不是直接生成子项,而是将其放在一个队列中,并有一个回调来处理队列中的下一个项目,并在它为空时调用nextfunc

let queue = [];

function step() {
    if (!queue.length)
        nextfunc(); // <-- ends here
    else
        travelDir(queue.shift())
}

function travelDir(directory) {
    ...
    dirReader.readEntries(parseEntries, errorfunc);
}

function parseEntries(subdirs) {
    subdirs.forEach(function (entry) {
        if (entry.isDirectory)
            queue.push(entry);
        else ...
            loadres(entry);
    });
    step() // <-- indirect recursion
}

queue.push(res_dir)
step()