-1

Problem is below I have a arr_x array, and I call "call_when_drop" function like below:

<body ondrop="call_when_drop(event,this);" ></body>

Then it begin to create array elements.when I console log array length I see only 1, but when I console log a few seconds later I see all number of members of array.But interesting thing is that when I console.log array it self I am able to see all elements.

below function is belong to here Does HTML5 allow drag-drop upload of folders or a folder tree?

var arr_x=[];
     function traverseFileTree(item, path,connection_time) {
        if(arr_x.length>25){
            return arr_x;
        }
        arr_x[arr_x.length]=arr_x.length;

  path = path || "";
  if (item.isFile) {
  } else if (item.isDirectory) {

    var dirReader = item.createReader();
    //console.log(dirReader);
    dirReader.readEntries(function(entries) {

      var dir=[];
      for (var i=0; i<entries.length; i++) {

       traverseFileTree(entries[i], path + item.name + "/",connection_time);


      }

    });
  }

  return arr_x;
}

This function called when user drop folder to browser

function call_when_drop(e,element){


 var items = e.dataTransfer.items;

    for (var i = 0, item; item = items[i]; ++i) {

      if (item.kind == 'file') {


          var a = traverseFileTree(item.webkitGetAsEntry(),"");


       console.log(arr_x);
     console.log('with_setTimeout');
        console.log(arr_x.length);
     console.log('---------------------------------------');
     setTimeout(function(){

        console.log('with_setTimeout');
        console.log(arr_x.length);

     },300);

      }
    }


}

Note: I notice that if I change traverseFileTree function like below it works but I need before function's working version

 function traverseFileTree(item, path,connection_time) {
if(arr_x.length>25){
    return arr_x;
}


arr_x[arr_x.length]=arr_x.length;
  traverseFileTree();
  return arr_x;
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129

1 Answers1

0

As this is clearly a chrome only question (webkitGetAsEntry function limits the usage) I can see how you could do it using good ol' Promises - not that only Chrome supports Promises, it's just that as it's a Chrome question, I can be certain Promises are available

Note: I see that at least firefox actually HAS webkitGetAsEntry function!!!)

var readEntriesPromise = function() {
    return new Promise((resolve, reject) => this.readEntries(resolve, reject));
};

function traverseFileTree(item, path, connection_time) {
    path = path || "";
    if (item.isDirectory) {
        var dirReader = item.createReader();
        dirReader.readEntriesPromise = readEntriesPromise;
        return dirReader.readEntriesPromise()
            .then(entries => entries.filter(entry => entry.isDirectory))
            .then(dirs => Promise.all(dirs.map(entry => traverseFileTree(entry, path + item.name + "/", connection_time))))
            .then(result => [].concat.apply([path + item.name], result));
    } else {
        return Promise.resolve("NO FOLDER"); // initial item was not a folder
    }
}

function call_when_drop(e, element) {
    var items = e.dataTransfer.items;
    [].filter.call(items, item => item.kind == 'file')
        .forEach(file => traverseFileTree(file.webkitGetAsEntry(), "")
            .then(function(results) {
                console.log(results);
            })
        )
}

Have tested in Firefox now that I know it has the webkitGetAsEntry function - proof of concept - https://jsfiddle.net/a5cggfq3/3/

Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
  • I need to detect index of dirReader like before in for – user7352487 Dec 29 '16 at 07:44
  • why, you don't use it anywhere – Jaromanda X Dec 29 '16 at 07:56
  • results in the final console.log is an array - therefore, each entry has an index – Jaromanda X Dec 29 '16 at 08:15
  • I have tested but when I drop folder which contain child folders, it doesnt work and only console.log parent folder – user7352487 Dec 29 '16 at 14:55
  • Really? I tested a folder with 37 subfolders and sure enough got 38 entire in the final result – Jaromanda X Dec 29 '16 at 14:57
  • Yes it only shows ["asd"], I have found another solution to all kind of asynchronous javascript isn't synchronous problems which is ` var refreshIntervalId = setInterval(function(){ if(before_len==folder_pathes.length){ clearInterval(refreshIntervalId); //It is ready to go } before_len=folder_pathes.length; },300);` .What about this solution?is that good? – user7352487 Dec 29 '16 at 15:15
  • using setInterval or setTimeout is a kludge - I can attest to the the code in both fiddles working correctly - although, I don't think I tested in chrome!! ironic if it worked in firefox, using webkitGetAsEntry bit not in Chrum! – Jaromanda X Dec 29 '16 at 15:18
  • okay probably you are right but your fiddle didnt worked for me,but anyway I will accept this answer because maybe someone need it in Firefox :) thanks – user7352487 Dec 29 '16 at 15:32
  • no, don't do that, let me test with a machine that has chrome (which I now have access to) – Jaromanda X Dec 29 '16 at 15:33
  • Okay I will wait your testing – user7352487 Dec 29 '16 at 15:39
  • https://jsfiddle.net/a5cggfq3/3/ seems to work for Chrome ... seems there is something wrong with the code in https://jsfiddle.net/a5cggfq3/ - even in firefox (though I did test it!!) – Jaromanda X Dec 29 '16 at 15:47
  • I've edited the answer, I think I may have had a version of the code that worked, but failed to save it in jsfiddle!! – Jaromanda X Dec 29 '16 at 15:52
  • It worked!!!, but I want to be sure that `readEntriesPromise` is that work cross browser? – user7352487 Dec 29 '16 at 15:59
  • it'll work in firefox and chrome ... for IE you'll need a miracle ... for Edge, I don't really know – Jaromanda X Dec 29 '16 at 16:11
  • a miracle - LOL , thats right , IE just created to prevent development – user7352487 Dec 29 '16 at 16:44