文件和目录条目 API 在 Chrome 中损坏?

File and Directory Entries API broken in Chrome?

我正在尝试使用文件和目录条目 API 创建一个文件上传工具,允许我将文件和目录的任意组合放入浏览器 window,以被阅读和上传。

(我完全知道可以通过使用启用了 webkitdirectory 的文件输入元素来实现类似的功能,但我正在测试一个用例,在该用例中,用户不会被迫将所有内容都放入单个文件夹)

使用拖放 API,我设法读取了 DataTransfer 项并使用 DataTransferItem.webkitGetAsEntry.[=24= 将它们转换为 FileSystemEntry 对象]

从那里,我可以判断条目是 FileSystemFileEntry 还是 FileSystemDirectoryEntry。我的计划当然是递归遍历目录结构,如果有的话,我应该可以使用 FileSystemDirectoryReader 方法 readEntries,像这样:

handleDrop(event) {
    event.preventDefault();
    event.stopPropagation();
    //assuming I dropped only one directory
    const directory = event.dataTransfer.items[0];
    const directoryEntry = directory.webkitGetAsEntry();
    const directoryReader = directoryEntry.createReader();
    directoryReader.readEntries(function(entires){
        // callback: the "entries" param is an Array 
        // containing the directory entries
    });
}

但是,我 运行 遇到以下问题:在 Chrome 中,readEntries 方法 只有 returns 100 个条目 。显然,这是预期的行为,因为从目录中获取后续文件的方式是再次调用 readEntries。但是,我发现这是不可能的。对该方法的后续调用会引发错误:

DOMException: An operation that depends on state cached in an interface object was made but the state had changed since it was read from disk.

有人知道解决这个问题的方法吗?对于 Chrome 中包含 100 多个文件的目录,这 API 是否无可救药地被破坏了? API 是否已弃用? (并不是说它曾经 "precated")。在 Firefox 中,readEntries returns 一次显示整个目录内容,这显然违反了规范,但它是可用的。

请指教

当然,我一发布这个问题,答案就打动了我。我试图做的类似于以下内容:

handleDrop(event) {
    event.preventDefault();
    event.stopPropagation();
    //assuming I dropped only one directory
    const directory = event.dataTransfer.items[0];
    const directoryEntry = directory.webkitGetAsEntry();
    const directoryReader = directoryEntry.createReader();
    directoryReader.readEntries(function(entries){
        // callback: the "entries" param is an Array 
        // containing the directory entries
    }, );
    directoryReader.readEntries(function(entries){
        //call entries a second time
    });
}

这个问题是 readEntries 是异步的,所以我试图在它 "busy" 读取第一批时调用它(我相信较低级别的程序员会有更好的术语).实现我想要做的事情的更好方法:

handleDrop(event) {
    event.preventDefault();
    event.stopPropagation();
    //assuming I dropped only one directory
    const directory = event.dataTransfer.items[0];
    const directoryEntry = directory.webkitGetAsEntry();
    const directoryReader = directoryEntry.createReader();

    function read(){
        directoryReader.readEntries(function(entries){
            if(entries.length > 0) {
                //do something with the entries
                read(); //read the next batch
            } else {
                //do whatever needs to be done after
                //all files are read
            }
        });
    }
    read();
}

这样我们可以确保 FileSystemDirectoryReader 在开始下一批之前完成一批。