从for循环中返回一个promise [英] return a promise from inside a for loop
问题描述
我有一个递归函数,我试图让它按顺序运行,每次都返回诺言。
代码是递归的,运行良好,但只适用于for循环中的第一项。
示例:
- 文件夹:1 - 确定
- 文件夹:11 - 确定 / li>
- 文件夹:111 - 确定
- 文件夹:2 - 不成功 / li>
- 所有异步下载按顺序完成。
我认为这是因为当我返回promise
函数CopySubFolders(folder,destFolder){
()函数(文件夹列表){
if(folderlist.size> 0){
for(var i); //递归拷贝每个子文件夹
return folder.getFoldersAsync()
.then在文件夹列表中){
var replace = Windows.Storage.CreationCollisionOption.replaceExisting;
console.log(create folder:+ folderlist [i] .name);
返回destFolder.createFolderAsync(folderlist [i] .name,替换)
.then(function(newdest){
return CopySubFolders(folderlist [i],newdest);
});
}
}
else {
return WinJS.Promise.as();
}
});
$ b CopySubFolders(folder,self.localFolder)
.then(function(){
completeFunc(Done);
console.log(按顺序完成所有异步下载);
})
任何想法如何在不中断for循环的情况下返回promise?
如果我使用forEach厕所,它不会被打断,但是后来我放弃了
示例:
是的,就像使用任何函数一样,如果执行
语句,函数将停止它正在做的事情并返回。你应该能够完成你想要做的事情:
编辑:如果你不需要它们来完成按照特定的顺序,你可以用 WinJS.Promise.join()
(aka Promise.all() code>在其他承诺方言中)和
map
(我将这里的内部分解为嵌套):
函数CopySubFolders(folder,destFolder){
return folder.getFoldersAsync()
.then(function(folderlist){
返回WinJS.Promise.join(folderlist.map(函数(文件夹){
返回CopyFolder(文件夹,destFolder);
});
});
}
函数CopyFolder(folder,destFolder){
var replace = Windows.Storage.CreationCollisionOption.replaceExisting;
console.log(create folder:+ folder.name);
返回destFolder.createFolderAsync(folder.name,替换)
.then(function(newdest){
return CopySubFolders(folder,newdest);
});
作为一个完整的附注,请不要使用 for ... in
与数组。这是一个坏主意。
作为这篇文章的一个痕迹,这里是如何你能够创建文件夹按顺序,如果你需要这是不建议的):
$ b $ pre $ 函数CopySubFolders(folder,destFolder){
var p = Promise.resolve() ;
$ b返回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 (函数(newdest){
return CopySubFolders(folder,newdest);
});
});
});
});
return p;
$ b
I have a recursive function and I am trying to make it run in sequence, returning the promise every time. The code is recursive and works well but works only for the first item in the for loop.
Example:
- folder: 1 - OK
- folder: 11 - OK
- folder: 111 - OK
- folder: 111 - OK
- folder: 2 - NOT OK
- folder: 12 - NOT OK
- All asynchronous downloads completed in sequence.
I think it is because when I return the promise from inside, then the for loop gets interrupted.
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.");
})
Any idea how to return the promise without interrupting the for loop?
PS: if I use a forEach loo it will not get interrupted, but then I loose the capability of returning the folders in sequence.
Example:
- folder: 1 - OK
- All asynchronous downloads completed in sequence.
- folder: 11 - OK
- folder: 111 - OK
- folder: 111 - OK
- folder: 2 - OK
- folder: 12 - OK
Yes, just like with any function, if you execute a return
statement, the function will stop what it's doing and return. You should be able to accomplish what you're trying to do with the following:
Edit: if you don't need them to complete in a specific sequence, you can accomplish what you are trying to do with WinJS.Promise.join()
(a.k.a. Promise.all()
in other promise dialects) and map
(I'm factoring out the inner part here to cut down on the nesting):
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);
});
}
As a complete side note, please don't use for...in
with arrays. It's a bad idea.
And as a bit of a vestige of this post, here is how you would be able to create the folders in sequence if you needed to (though that is not recommended):
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;
}
Another slightly cleaner way to do the same thing, as illustrated here, is to use 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());
});
}
这篇关于从for循环中返回一个promise的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!