javascript - 检测 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")
}
解决方案
我想出了一个可能的答案。
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。
推荐阅读
- php - 如何在 laravel 视图刀片中显示来自数据库列的 Json 编码数据
- php - PHP字符串比较问题
- c# - 将数据库服务器移动到 Azure 时,除了连接字符串之外,sql 连接还有哪些变化?
- angular - 使用 Ionic 的低质量 OL 地图
- azure - 如何使用 Azure Active Directory 为外部应用程序设置客户端凭据流
- excel - 如何使用代码在信任中心启用宏设置
- oracle - 如何在 Oracle 和 SQL Server 中的 case 表达式的结果中使用数学表达式
- r - 如何重新排列数据框?
- logstash - 安装 logstash ubuntu 后 /etc/init.d 中缺少 Logstash 文件
- spring - onPartitionsRevokedBeforeCommit 与 onPartitionsRevokedAfterCommit