簡體   English   中英

從for循環中返回一個promise

[英]return a promise from inside a for loop

我有一個遞歸函數,我試圖使其按順序運行,每次都返回諾言。 該代碼是遞歸的,並且運行良好,但僅適用於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?

PS:如果我使用forEach loo,它不會被打斷,但是我失去了按順序返回文件夾的功能。

例:

  • 文件夾:1-確定
  • 所有異步下載均按順序完成。
  • 文件夾:11-確定
  • 文件夾:111-確定
  • 文件夾:111-確定
  • 文件夾:2-確定
  • 文件夾:12-確定

是的,就像任何函數一樣,如果執行return語句,該函數將停止正在執行的操作並返回。 您應該能夠完成以下工作:

編輯:如果您不需要它們按特定順序完成,則可以完成WinJS.Promise.join() (在其他Promise.all()方言中也稱為Promise.all() )和map (我m在這里分解內部部分以減少嵌套):

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());
    });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM