首页 > 解决方案 > 检测 vanilla js 中文件夹删除事件的完成

问题描述

我正在尝试确定在将目录树拖放到页面后是否已完全遍历目录树。即:我想知道在整个文件夹和子目录被drop事件代码处理之后,下一个进程什么时候可以开始。

例如,在下面的代码中,我想通过 json 将 M.files 发送到服务器。为此,我需要知道文件夹何时被处理。未显示 Ajax 调用。

递归目录树遍历函数:

async function processEnt(ent,n,fls){
    n = n==undefined? 0:n;
    
 
    if( ent.isFile ){
        fls.files.push(ent.name)        
    }    
    else if (ent.isDirectory){
        
        fls.dirs[ent.name]={ "files":[], "dirs":{},"done":false }                
        var r = ent.createReader()        
        
        await r.readEntries(
            async function f(ents){                                                
                if(ents.length >0){                    
                    for(var e of ents){
                       await processEnt(e,n+1,fls.dirs[ent.name])                    
                    }                                 
                    await r.readEntries(f)
                }
                
            }
        )
        
    }    
    console.log(n +" level done")    
        
}


   

掉落事件功能:

async function onDrop(evt){
    evt.preventDefault()
    evt.stopPropagation()
    
    M.files = {
        "files":[],
        "dirs":{}
    }    
    for(item of evt.dataTransfer.items){                
        await processEnt( item.webkitGetAsEntry(),0,M.files )    
    }
    
    console.log("on drop done")
    
}

标签: javascript

解决方案


我想出了一个可能的答案。

M.paths保存活动路径的数量,并在第一个之后的每个子目录中递增。文件和目录的处理也略有改变。计时器用于对所有路径进行极化M.paths以查看是否所有路径都已完成。

可能存在竞争条件,即第一个子目录被处理并M.paths在该级别上的任何其他目录被处理之前递减。

掉落事件:

function onDrop(evt){
    evt.preventDefault()
    evt.stopPropagation()
            
   
    M.paths = 0 
    M.files = {
        "files":[],
        "dirs":[]
    }    
    
    for(item of evt.dataTransfer.items){                
        ent = item.webkitGetAsEntry()
        if(ent.isFile){
           M.files["files"].push(ent) 
        }else if(ent.isDirectory) {
            M.paths+=1
            processDirectory(ent,0,M.files )                
        }
    }
    
    window.setTimeout(function f(){
            if(M.paths==0){
                // drop envent processed 
                //run update or send info to server
                console.log("Drop event done")                    
                
            }else{
                window.setTimeout(f,500)
            }
        },500)
} 

处理每个目录的函数:

function processDirectory(ent,n,fls){
    n = n==undefined? 0:n;
        
    var new_dir ={"ent":ent,"files":[],"dirs":[]}
    fls["dirs"].push(new_dir)
    var r = ent.createReader()        
    r.readEntries(
        function f(ents){                                                                
            var leaf = true
            var add_path =0
            for(let entc of ents){
                if ( entc.isDirectory ){
                    M.paths+= add_path
                    add_path = 1
                    console.log(n+":"+M.paths+":"+entc.name)
                    leaf = false
                    processDirectory(entc,n+1,new_dir)
                    
                }else if( entc.isFile){
                    new_dir["files"].push(ent)
                }     
            }
            if(leaf){ M.paths--}                
        }            
    )   
}

这似乎有效,尽管我没有彻底测试过。此外,如果有很多条目,它不会得到所有条目。有关详细信息,请参阅https://stackoverflow.com/a/53058574/2975893


推荐阅读