javascript - 使用循环中的嵌套 promise 控制流程

标签 javascript jquery angularjs promise bluebird

我在使用 promises 控制方法流程时遇到问题:

//FIND CHECKED OUT FILES
getCheckedOutFiles = function () {
    console.log('Get checked out files');
    var d = $q.defer();

    // Store final results and pass to then callback
    var checkedOutFiles = window.x = [];

    // Promise, returns collection with all sites 
    SiteService.getAllSites()
        .then(sites => {
            // For each site get lists then get items matching filter
            sites.forEach(function (site) {
                var web = new $pnp.Web(site.url);

                return web.lists
                    .filter("BaseTemplate eq 101")
                    .get() // Returns promise with all lists matching filter 
                    .then(lists => {
                        // Go through each list and find matching item 
                        lists.forEach(function (list) {
                            web.lists.getByTitle(list.Title).items
                                .filter("CheckoutUser ne null")
                                .expand("File, File/Author, File/ModifiedBy, File/CheckedOutByUser")
                                .get() // Returns promise with all items matching filter 
                                .then(files => {
                                    // Loop through each item, get properties, add to collection 
                                    files.forEach(function (f) {
                                        var fileObject = {
                                            fileName: f.File.Name,
                                            fileUrl: f.File.ServerRelativeUrl,
                                            absoluteUrl: f.File.ServerRelativeUrl,
                                            checkedTo: f.File.CheckedOutByUser.Title,
                                            modified: f.Modified,
                                            modifiedBy: f.File.ModifiedBy.Title,
                                            createdBy: f.File.Author.Title,
                                            created: f.Created,
                                            version: f.File.UIVersionLabel
                                        };
                                        // Add file to collection 
                                        checkedOutFiles.push(fileObject);
                                    }, this);
                                })
                                .catch(e => {
                                    console.log(e);
                                });
                        });
                        // "Ideally" - When all files retrieved return collection of results 
                        d.resolve(checkedOutFiles);
                        return null;
                    })
                    .catch(e => {
                        console.log(e);
                    });
            }, this);
            return null;
        });
    return d.promise;
};

// Returns promise with all checkedout file 
getCheckedOutFiles().then(files => {
    console.log("RESULTS", files);
    d.resolve(files);
});

我注意到 console.log("RESULTS", files); 将在调用完成之前打印出来。调用完成后,window.x 将包含预期的数据。

最佳答案

使用Promise.all()等待创建的所有 promise ,然后解决父级 promise

像这样(未测试)

//FIND CHECKED OUT FILES
getCheckedOutFiles = function () {
    console.log('Get checked out files');
    var d = $q.defer();

    // Store final results and pass to then callback
    var checkedOutFiles = window.x = [];

    // Promise, returns collection with all sites 
    SiteService.getAllSites()
        .then(sites => {
            // For each site get lists then get items matching filter
            sites.forEach(function (site) {
                var web = new $pnp.Web(site.url);

                return web.lists
                    .filter("BaseTemplate eq 101")
                    .get() // Returns promise with all lists matching filter 
                    .then(lists => {
                        let promises = []
                        // Go through each list and find matching item 
                        lists.forEach(function (list) {

                            let prom = web.lists.getByTitle(list.Title).items
                                .filter("CheckoutUser ne null")
                                .expand("File, File/Author, File/ModifiedBy, File/CheckedOutByUser")
                                .get() // Returns promise with all items matching filter 
                                .then(files => {
                                    // Loop through each item, get properties, add to collection 
                                    files.forEach(function (f) {
                                        var fileObject = {
                                            fileName: f.File.Name,
                                            fileUrl: f.File.ServerRelativeUrl,
                                            absoluteUrl: f.File.ServerRelativeUrl,
                                            checkedTo: f.File.CheckedOutByUser.Title,
                                            modified: f.Modified,
                                            modifiedBy: f.File.ModifiedBy.Title,
                                            createdBy: f.File.Author.Title,
                                            created: f.Created,
                                            version: f.File.UIVersionLabel
                                        };
                                        // Add file to collection 
                                        checkedOutFiles.push(fileObject);
                                    }, this);
                                })
                                .catch(e => {
                                    console.log(e);
                                });
                            promises.push(prom)
                        });
                        // "Ideally" - When all files retrieved return collection of results 
                        Promise.all(promises).then(function(){
                            d.resolve(checkedOutFiles);
                        })
                        return null;
                    })
                    .catch(e => {
                        console.log(e);
                    });
            }, this);
            return null;
        });
    return d.promise;
};

// Returns promise with all checkedout file 
getCheckedOutFiles().then(files => {
    console.log("RESULTS", files);
    d.resolve(files);
});

关于javascript - 使用循环中的嵌套 promise 控制流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46046487/

相关文章:

jquery - 无法使用 jquery 定位使用 Mustache.js 渲染的元素

javascript - 在 Angular JS 中观察全局对象的属性

javascript - 在 Controller 中获取每个指定类型的名称

javascript - 如何在单击按钮时添加文本框?

javascript - 如何在 Angular 2 模板中使用外部 Javascript 函数?

javascript - 如何使用 CSS 为最后一个元素设置边框?

javascript - 使用 Node 本地化

javascript - 使用 vuejs 和 axios 显示来自 JSON API 的数据

jQueryeach只影响最后一个元素

javascript - jquery将输入val添加在一起