【发布时间】:2020-06-27 22:07:08
【问题描述】:
我很难获得按我需要的方式工作的承诺。我尝试了许多不同的方法来解决这个承诺,但我所做的一切都无法满足我的需要。我正在尝试在网页上拖放文件。我需要传递给调用以上传文件的 Set (this.files) 中所有文件的列表。问题是 Promise.all 是在 Promise 完成之前运行的。
我仍在努力将我的想法包裹在承诺上,所以也许我错了,但从我的所有研究看来,这应该可行。任何帮助将不胜感激。
async dndDropFiles(event) {
event.preventDefault();
let ptable = [];
this.files = new Set();
if (event.dataTransfer.types[0] === "Files") {
var items = event.dataTransfer.items;
for (var i=0; i<items.length; i++) {
// webkitGetAsEntry is where the magic happens
var item = await items[i].webkitGetAsEntry();
if (item) {
ptable.push(new Promise(async resolve => {
resolve(await this.dndTraverseFileTree(item, ""));
}))
}
}
Promise.all(ptable)
.then( (results) => {
if (this.files.size > 0) {
this.progress = this.uploadService.upload(this.files, this.currentDir, this.currentProject);
}
})
}
}
async dndTraverseFileTree(item, path) {
if (item.isFile) {
// Get file
item.file((file) => {
this.files.add(file);
});
} else if (item.isDirectory) {
// Get folder contents
let ptable = [];
var dirReader = await item.createReader();
dirReader.readEntries((entries) => {
for (var i=0; i<entries.length; i++) {
ptable.push(new Promise( async resolve => {
resolve(await this.dndTraverseFileTree(entries[i], path + item.name + "/"));
}));
}
Promise.all(ptable)
.then (results => {});
});
}
}
【问题讨论】:
-
哇,什么微任务魔法:
new Promise(async resolve1 => resolve(await new Promise(resolve2 => resolve2()))- 只是想知道你需要这个微任务魔法还是你的意思是(new Promise(r=>r())).then(r=>r)? -
我在没有异步的情况下尝试过,但它也不起作用。你认为这会影响 Promise 的解决吗?
-
问题是你有点混合了异步糖和承诺然后还创建了冗余承诺 - 我试一试并重写你的代码
-
我从函数中提取了所有异步和等待,但我没有看到任何真正不同的地方。我仍然可以看到我放入的 cmets 中的所有文件,但它仍然会在承诺完成之前解决 Promise.all。我必须在解决承诺的方式上做错了。
-
你想递归循环目录中的所有文件,然后将它们添加到数组中,然后上传它们吗?但是您需要等待所有这些都立即添加,因为每个
item.file()都是异步的?我会在item.file()中返回一个新的new Promise(),然后用let promise = item.file(() => return new Promise(() => //add file here and call resolve))之类的变量捕获它,然后添加ptable.push(promise)。最后我会使用Promise.all()。我脑子里没有一个清晰的结构,但如果你能创建一个类似沙盒的例子,我可以试试。
标签: javascript angular promise es6-promise