清除以前拖动的文件条目?

时间:2014-03-15 05:37:19

标签: javascript google-chrome drag-and-drop promise

我有以下脚本要用于上传文件。它运行正常,但是我无法找到为什么每次上传新文件时都会出现拖动的上一个文件。由于程序的异步性质,我在调试时遇到了问题。

小提琴:

http://jsfiddle.net/tekky/PYTBw/

代码:

var dndbox = $(".dndbox")[0];

dndbox.addEventListener("dragenter", function(e) {
    e.stopPropagation();
    e.preventDefault();
},false);

dndbox.addEventListener("dragover", function(e) {
    e.stopPropagation();
    e.preventDefault();
},false);

dndbox.addEventListener("drop", function(e) {
    e.stopPropagation();
    e.preventDefault();

    var itemList = e.dataTransfer.items;

    var fp = [];

    var traverse = function(entry)
        {
            if (entry.isFile) {
                entry.file(function(file) {
                    var filepromise = new Promise(function(res, rej) {
                        res(file);
                    });
                    fp.push(filepromise);
                });
            } else if (entry.isDirectory){
                var dR = entry.createReader();
                dR.readEntries(function(entries) {
                    for(var i = 0; i < entries.length; i++)
                    {
                        traverse(entries[i]);
                    }
                });
            }
        }

        var collection = [];
        for(var i = 0; i < itemList.length; i++) {
            var e = itemList[i].webkitGetAsEntry();
            var tp = new Promise(function(r, rj) {
                traverse(e);
                r(fp);
            });
            collection.push(tp);
        }

        Promise.all(collection).then(function(ff) {
            $(".prompt").show();
            $(".prompt").on("click", function() {
                $(this).hide();
                ff.forEach(function(pa) {
                    pa.forEach(function(p){
                        p.then(function(f)
                        {
                            console.log(f);
                        });

                    });
                });
            });
        });
},false);

1 个答案:

答案 0 :(得分:1)

  

每次上传新文件时,前一个拖动的文件也会出现。

这不是由traverse的异步性质造成的,与承诺无关。这是由于这种结构:

// left away some irrelevant callbacks
dndbox.addEventListener("drop", function(e) {
    var fp = [];
    // add entries to fp
    $(".prompt").on("click", function() {
        console.log(fp);
    });
}, false);

正如您所看到的,每次删除某些内容时,您都会创建一个新列表并向(相同)元素添加一个侦听器,从现在起上的记录该列表。要解决这个问题,您可以:

  • 仅使用一个全局列表,在新的丢弃事件的情况下将被覆盖
  • 为每个要记录的列表创建一个新的.prompt元素
  • 在触发器被触发时卸载它,以便不会再次触发它。您可以使用jQuery .one() method

除此之外,你非常奇怪地使用Promise(不是说,错误)。 collection是使用仍为空的fp数组立即解析的promise的列表。您很幸运,当触发click回调时,所有文件都被读入。尽管如此,您pa的每个=== fp仍然是fp,因此您itemList中的每个项目记录的次数与function traverse(entries) var collection = []; for (var i=0; i<entries.length; i++) { var entry = entries[i]; if (entry.isFile) { collection.push(new Promise(function(res, rej) { entry.file(res); })); } else if (entry.isDirectory){ collection.push(new Promise(function(res, rej) { var dR = entry.createReader(); dR.readEntries(res); }).then(traverse)); } } return Promise.all(collection).then(function(results) { // flatten return [].concat.apply([], results); }); } var entries = []; for(var i = 0; i < itemList.length; i++) entries[i] = itemList[i].webkitGetAsEntry(); traverse(entries).then(function(fp) { $(".prompt").show().one("click", function() { $(this).hide(); fp.forEach(console.log, console); }); }); 的长度相同。

请查看Understanding promises in node.js for recursive functionIs there an example of using raw Q promise library with node to recursively traverse a directory asynchronously?,了解如何正确执行此操作。在你的情况下,它就像

{{1}}