【问题标题】:Asynchronous drag and drop multiple files / directories not awaiting properly异步拖放多个文件/目录未正确等待
【发布时间】:2021-07-05 22:09:20
【问题描述】:

虽然代码正确并最终获取所有子目录中的所有文件路径,但文件数组在 handleDrop 末尾为空,并且没有正确等待 walkDirRecursively。

我已经尝试添加 Promise 和解决等,但它没有正确等待。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <style>
        #dropzone {
            width: 100vw;
            height: 100vh;
        }
    </style>
    <title>Document</title>
</head>
<body>
    <div id="dropzone" ondragover="handleDragOver(event)" ondrop="handleDrop(event)"></div>
    
    <script>
        let files = [];

        function handleDragOver(event) {
            event.preventDefault();
        }

        async function handleDrop(event) {
            event.preventDefault();
            files = [];
            
            const dataTransferItems = Object.keys(event.dataTransfer.items);

            await dataTransferItems.map(async (key) => {
                const item = event.dataTransfer.items[key];
                const entry = item.webkitGetAsEntry();
                
                if (!entry) return;

                if (entry.isFile) {
                    files.push(entry.fullPath);
                } else if (entry.isDirectory) {
                    const directoryReader = entry.createReader();
                    await walkDirRecursively(entry.fullPath, directoryReader);
                }
            });

            console.log(files);

        }

        function walkDirRecursively(path, directoryReader) {
            return new Promise(async (resolve, reject) => {
                directoryReader.readEntries(async (entries) => {
                    await entries.map(async (entry) => {
                        if (entry.isFile) {
                            const newPath = path + "/" + entry.name;
                            files.push(newPath);
                        } else if (entry.isDirectory) {
                            const newPath = path + "/" + entry.name;
                            const newDirectoryReader = entry.createReader();
                            await walkDirRecursively(newPath, newDirectoryReader);
                        }
                    });
                });
                resolve();
            });
        }
    </script>
</body>
</html>

在页面上放置一个文件夹后,试用该示例应该会说明问题。

【问题讨论】:

    标签: javascript async-await drag-and-drop


    【解决方案1】:

    将 Promise.all 添加到两个循环中并将 walkDirRecursively 包装在 Promise 中,并且仅在内部循环完成时才解决它。

    还添加了字母排序,因为它似乎是临时处理文件/文件夹,而不是按照操作系统存储它们的顺序。

        async function handleDrop(event) {
            event.preventDefault();
            files = [];
            
            const dataTransferItems = Object.keys(event.dataTransfer.items);
    
            console.log(dataTransferItems);
    
            await Promise.all(dataTransferItems.map(async (key) => {
                const item = event.dataTransfer.items[key];
                const entry = item.webkitGetAsEntry();
                
                if (!entry) return;
    
                if (entry.isFile) {
                    files.push(entry.fullPath);
                } else if (entry.isDirectory) {
                    const directoryReader = entry.createReader();
                    return await walkDirRecursively(entry.fullPath, directoryReader);
                }
            }));
    
            console.log(files);
        }
    
    
        function walkDirRecursively(path, directoryReader) {
            return new Promise(async (resolve, reject) => {
                directoryReader.readEntries(async (entries) => {
                    await Promise.all(sortListAlphabetically(entries).map(async (entry) => {
                        if (entry.isFile) {
                            const newPath = path + "/" + entry.name;
                            files.push(newPath);
                        } else if (entry.isDirectory) {
                            const newPath = path + "/" + entry.name;
                            const newDirectoryReader = entry.createReader();
                            await walkDirRecursively(newPath, newDirectoryReader);
                        }
                    }));
                    resolve();
                });
            });
        }
    
        function sortListAlphabetically(list) {
            return list.sort((a, b) => a.name.localeCompare(b.name));
        }
    

    【讨论】:

      猜你喜欢
      • 2020-09-10
      • 1970-01-01
      • 1970-01-01
      • 2019-03-03
      • 2018-02-13
      • 2015-05-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多