代码之家  ›  专栏  ›  技术社区  ›  David_Zizu

在javascript中将承诺的结果组合成一个数组

  •  0
  • David_Zizu  · 技术社区  · 6 年前

    我尝试将作为目录上传的所有文件解析为单个文件数组。我有一个问题,我不能将所有承诺的结果组合成一个数组。我得到了一个多维数组。

    function iterateThroughUploadedFiles(files, isEntry = false) {
        var promises = [];
        for (let i = 0; i < files.length; i++) {
            let entry = isEntry ? files[i].webkitGetAsEntry() : files[i];
            if (entry.isFile) {
                promises.push(new Promise(function(resolve, reject) {
                    getFile(entry, resolve, reject);
                }));
            }
            else if (entry.isDirectory) {
                let dirReader = entry.createReader();
    
                var promise = new Promise(function(resolve, reject) {
                    readEntries(dirReader, resolve, reject);
                });
    
                promises = promises.concat(promise);
            }
        }
        return Promise.all(promises);
    }
    
    function getFile(fileEntry, resolve, reject) {
        fileEntry.file(function(file) {
            resolve(file)
        });
    }
    
    function readEntries(dirReader, resolve, reject) {
        dirReader.readEntries(function (entries) {
            resolve(iterateThroughEntries(entries).then(function(result) {
                return result;
            }));
        });
    }
    

    用法:

    iterateThroughUploadedFiles(files, true).then(function(result) {
        console.log(result);
    });
    

    当我执行 iterateThroughUploadedFiles 功能 result 变量是多维数组。但是,我希望此数组扁平化(例如: [文件(6148),数组(1),数组(0),文件(14)] )。我不太熟悉回电和承诺……因此,我在与他们合作时遇到了一些问题。

    编辑:
    我在里面做了一个打字错误 readEntries(dirReader, resolve, reject) 功能。应该有 迭代上载的文件 而不是 iterateThroughEntries 功能。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Jonas Wilms    6 年前
    return Promise.all(promises);
    

    它可以解析为二维数组,使用一些生成器函数可以很容易地将其展平:

    function* flatten(arr) {
      for(const el of arr) {
        if(Array.isArray(el)) {
          yield* flatten(el);
        } else {
          yield el;
        }
      }
    }
    
    return Promise.all(promises).then(array => ([...flatten(array)]));
    

    路过时 resolve reject 工作的方式,可以做得更优雅,只要返回一个新的承诺从 getFile 功能:

    function getFile(fileEntry, resolve, reject) {
       return new Promise(resolve => fileEntry.file(resolve));
    }
    

    然后它就可以很容易地被锁起来

    function readEntries(dirReader) {
      return new Promise(resolve => dirReader.readEntries(resolve))
        .then(iterateThroughEntries);
    }
    
    function iterateThroughUploadedFiles(files, isEntry = false) {
       return Promise.all( files.map( file => {
         let entry = isEntry ? file.webkitGetAsEntry() : file;
         if (entry.isFile) {
           return getFile(entry);
         } else if (entry.isDirectory) {
           return readEntries( entry.createReader());
         }
       })).then(array => ([...flatten(array)]));
    }