Javascript 仅在完成异步递归函数后延迟函数执行。
我用拖放创建了一个文件上传表单,它递归地遍历被删除的文件夹,上传文件和文件夹,并将它们添加到JSTree实例中 这是回拨电话Javascript 仅在完成异步递归函数后延迟函数执行。,javascript,recursion,promise,Javascript,Recursion,Promise,我用拖放创建了一个文件上传表单,它递归地遍历被删除的文件夹,上传文件和文件夹,并将它们添加到JSTree实例中 这是回拨电话 function drop(evt){ evt.stopPropagation(); evt.preventDefault(); //get selected node (created by jsTree) var parent_id = $('#treeContainer').jstree('get_selected').attr(
function drop(evt){
evt.stopPropagation();
evt.preventDefault();
//get selected node (created by jsTree)
var parent_id = $('#treeContainer').jstree('get_selected').attr('data-attr-itemid');
var theNodeId = $('#treeContainer').jstree('get_selected').attr('id');
for (var i=0; i<items.length; i++) {
var item = items[i].webkitGetAsEntry();
if (item) {
traverseFileTree2(item,parent_id,theNodeId);
}
}
//THIS RUNS BEFORE RECUSIVE FUNCTION IS COMPLETED
addFilesToUploadQueue(filesToQueue);
}
功能下降(evt){
evt.stopPropagation();
evt.preventDefault();
//获取所选节点(由jsTree创建)
var parent_id=$('#treeContainer').jstree('get_selected').attr('data-attr-itemid');
var theNodeId=$('#treeContainer').jstree('get#u selected').attr('id');
对于(var i=0;i’;
变量数据={'parent\u id':parent\u id,'name':dirName,'type':'Directory'};
$.post(url、数据、函数(结果){
//将目录节点添加到目录树
$(“#treeContainer”).jstree('open#u node','#'+节点ID);
$(“#treeContainer”).jstree('create','#'+节点ID,'last',result,null,true);
父项id=结果[“属性”][“数据属性项id”];
theNodeId=result[“attr”][“id”];
var dirReader=item.createReader();
dirReader.readEntries(函数(条目){
对于(var i=0;i,这绝对是你可以用承诺来解决的问题
设计traverseFileTree2()
,使其始终返回承诺/延迟,即使您实际上没有启动任何异步操作。
- promise的成功处理程序应该提供它找到的文件列表
- 如果启动一组递归调用,请列出它们的承诺,并使用
$.when()
等待它们全部完成,然后再对它们执行操作
类似地,在主循环中,收集顶级承诺的列表(从traverseFileTree2()
),然后再次使用$。when()
将它们组合成一个承诺,当所有承诺都结束时,“完成”,聚合它们的文件列表。(没有共享的filesToQueue
变量,都是返回值。)
将addFilesToUploadQueue()
设置为在这个巨大的最后承诺成功时调用,将承诺的文件返回数据带到队列中
这里有一个未经测试的重写,但即使它有足够的缺陷,希望能让大家理解这个想法:
function drop(evt){
evt.stopPropagation();
evt.preventDefault();
//get selected node (created by jsTree)
var parent_id = $('#treeContainer').jstree('get_selected').attr('data-attr-itemid');
var theNodeId = $('#treeContainer').jstree('get_selected').attr('id');
var promises = [];
for (var i=0; i<items.length; i++) {
var item = items[i].webkitGetAsEntry();
if (item) {
promises.push(traverseFileTree2(item,parent_id,theNodeId));
}
}
$.when(promises).then(function(filesToQueue){
addFilesToUploadQueue(filesToQueue);
});
}
功能下降(evt){
evt.stopPropagation();
evt.preventDefault();
//获取所选节点(由jsTree创建)
var parent_id=$('#treeContainer').jstree('get_selected').attr('data-attr-itemid');
var theNodeId=$('#treeContainer').jstree('get#u selected').attr('id');
var承诺=[];
for(var i=0;i.file()是异步的
function drop(evt){
evt.stopPropagation();
evt.preventDefault();
//get selected node (created by jsTree)
var parent_id = $('#treeContainer').jstree('get_selected').attr('data-attr-itemid');
var theNodeId = $('#treeContainer').jstree('get_selected').attr('id');
var promises = [];
for (var i=0; i<items.length; i++) {
var item = items[i].webkitGetAsEntry();
if (item) {
promises.push(traverseFileTree2(item,parent_id,theNodeId));
}
}
$.when(promises).then(function(filesToQueue){
addFilesToUploadQueue(filesToQueue);
});
}
function traverseFileTree2(item, parent_id, theNodeId, path) {
var ret = $.Deferred();
if (item.isFile) {
var files = [];
// What is .file()?? I'm assuming it's synchronous right now
item.file(function(file){
//add parent id, and adds to array to be queued for upload
file.parent_id = parent_id;
files.push(file);
});
ret.resolve(files)
} else if (item.isDirectory) {
var dirName = item.name;
var url = '<?php echo $this->Html->url(array('controller'=>'nodes', 'action'=>'addchild'));?>';
var data = {'parent_id':parent_id, 'name':dirName, 'type':'Directory'};
$.post(url,data,function(result){
var promises = [];
//adds directory node to tree
$("#treeContainer").jstree('open_node','#'+theNodeId);
$("#treeContainer").jstree('create', '#'+theNodeId, 'last', result,null,true);
parent_id = result["attr"]["data-attr-itemid"];
theNodeId = result["attr"]["id"];
var dirReader = item.createReader();
// Assuming readEntries() is syncrhonous
dirReader.readEntries(function(entries) {
for (var i=0; i<entries.length; i++) {
promises.push(traverseFileTree2(entries[i], parent_id, theNodeId, path + item.name + "/"));
}
});
$.when(promises).then(function(){
// IIRC each argument will be the return value of one of the promises
var files = [];
for(var i = 0; i < arguments.length; i++){
files.concat(arguments[i]);
}
ret.resolve(files);
},function(){
ret.fail();
});
}, 'json');
}
return ret.promise(); // .promise() is "safer" in terms of keeping code isolated
}