我有一个递归函数,我试图让它按顺序运行,每次都返回promise。 代码是递归的并且运行良好,但仅适用于for循环中的第一项。
示例:
我认为这是因为当我从内部返回promise时,for循环就会被中断。
function CopySubFolders(folder, destFolder) {
// Recursively copy each subfolder
return folder.getFoldersAsync()
.then(function (folderlist) {
if (folderlist.size > 0) {
for (var i in folderlist) {
var replace = Windows.Storage.CreationCollisionOption.replaceExisting;
console.log("create folder: " + folderlist[i].name);
return destFolder.createFolderAsync(folderlist[i].name, replace)
.then(function (newdest) {
return CopySubFolders(folderlist[i], newdest);
});
}
}
else {
return WinJS.Promise.as();
}
});
}
CopySubFolders(folder, self.localFolder)
.then(function () {
completeFunc("Done");
console.log("All asynchronous downloads completed in sequence.");
})
知道如何在不中断for循环的情况下返回promise吗?
PS:如果我使用forEach厕所它不会被打断,但是我失去了按顺序返回文件夹的能力。
示例:
答案 0 :(得分:4)
是的,就像使用任何函数一样,如果执行return
语句,该函数将停止它正在执行和返回的内容。您应该能够完成以下所做的事情:
编辑:如果您不需要按特定顺序完成这些操作,则可以使用WinJS.Promise.join()
(又名Promise.all()
完成您要执行的操作在其他承诺方言)和map
(我在这里分解内部部分以减少嵌套):
function CopySubFolders(folder, destFolder) {
return folder.getFoldersAsync()
.then(function (folderlist) {
return WinJS.Promise.join(folderlist.map(function (folder) {
return CopyFolder(folder, destFolder);
});
});
}
function CopyFolder(folder, destFolder) {
var replace = Windows.Storage.CreationCollisionOption.replaceExisting;
console.log("create folder: " + folder.name);
return destFolder.createFolderAsync(folder.name, replace)
.then(function (newdest) {
return CopySubFolders(folder, newdest);
});
}
作为完整的附注,请不要将for...in
与数组一起使用。这是一个坏主意。
作为这篇文章的一个遗迹,如果你需要,你可以按顺序创建文件夹(虽然不建议这样做):
function CopySubFolders(folder, destFolder) {
var p = Promise.resolve();
return folder.getFoldersAsync()
.then(function (folderlist) {
return folderlist.forEach(function (folder) {
var replace = Windows.Storage.CreationCollisionOption.replaceExisting;
console.log("create folder: " + folder.name);
p = p.then(function () {
destFolder.createFolderAsync(folder.name, replace)
.then(function (newdest) {
return CopySubFolders(folder, newdest);
});
});
});
});
return p;
}
如图here所示,做同样事情的另一种稍微清洁的方法是使用folderlist.reduce()
:
function CopySubFolders(folder, destFolder) {
return folder.getFoldersAsync()
.then(function (folderlist) {
return folderlist.reduce(function (sequence, folder) {
var replace = Windows.Storage.CreationCollisionOption.replaceExisting;
console.log("create folder: " + folder.name);
return sequence.then(function () {
destFolder.createFolderAsync(folder.name, replace)
.then(function (newdest) {
return CopySubFolders(folder, newdest);
});
});
}, Promise.resolve());
});
}