从for循环内部返回promise
return a promise from inside a for loop
我有一个递归函数,我试图让它按顺序运行,每次都返回promise。该代码是递归的,运行良好,但仅适用于for循环中的第一项。
示例:
- 文件夹:1-确定
- 文件夹:11-确定
- 文件夹:111-确定
- 文件夹:111-确定
- 文件夹:2-不正常
- 文件夹:12-不正常
- 所有异步下载按顺序完成
我想这是因为当我从内部返回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吗?
附言:如果我使用forEach厕所,它不会被打断,但我失去了按顺序返回文件夹的能力。
示例:
- 文件夹:1-确定
- 所有异步下载按顺序完成
- 文件夹:11-确定
- 文件夹:111-确定
- 文件夹:111-确定
- 文件夹:2-确定
- 文件夹:12-确定
是的,就像任何函数一样,如果执行return
语句,函数将停止它正在执行的操作并返回。你应该能够完成你试图用以下东西做的事情:
编辑:如果您不需要它们按特定顺序完成,您可以使用WinJS.Promise.join()
(在其他promise方言中也称为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;
}
如图所示,另一种稍微干净一点的方法是使用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());
});
}
相关文章:
- 在promise完成后,依次运行返回promise的函数
- 等待's返回Promise而不是value
- 当数组中的某个函数没有返回promise时,我可以使用$q.all吗
- 可以为云端点打开.client.load返回promise
- 使用从内部函数返回的异步数据对外部函数返回promise
- 在Angular服务中使用$http时,为什么要返回promise和数据
- 从自定义函数返回promise
- Leadfoot会话对象返回promise
- For循环以错误的顺序返回promise
- 返回promise而不是jquery ajax调用
- 当异步验证器在AngularJS中返回promise时提交表单
- 函数返回Promise,检查错误
- 在jQuery中返回promise()或deferred有什么区别
- 在 JavaScript 中,当 'parent()' 返回 Promise 时,如何实现递归的 'ancestors(
- Angular$q返回promise两次$http服务调用
- 对返回promise的函数使用.success时,Undefined不是函数
- 返回promise的链接函数;刷新超时后无法解析
- Angular Service在返回promise时抛出异常
- 模拟服务返回promise:无法读取未定义的属性
- 这个JavaScript函数需要返回Promise吗