我无法使用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
将包含预期的数据。
答案 0 :(得分:1)
使用Promise.all()等待创建的所有承诺,然后解决父承诺
像这样(未经测试)//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);
});
答案 1 :(得分:1)
这些是需要修复的事情:
您有两个单独的循环,您有承诺管理。你需要在数组中收集这些promise,然后在它们上使用Promise.all()
来知道循环中的所有promise都已完成。
您通过创建d
承诺使用反模式,然后手动解析它。相反,您应该返回SiteService.getAllSites().then()
承诺,然后在其中,返回承诺链,以便所有内容都链接(包括正确的错误处理)。
刚刚登录的.catch()
处理程序正在“吃”错误。如果您.catch()
并且不重新抛出,它会将该承诺变为已解决的承诺,从而“吃掉”错误而不是传播它。
以下是解决这些问题的方法:
//FIND CHECKED OUT FILES
function getCheckedOutFiles() {
console.log('Get checked out files');
// Store final results and pass to then callback
var checkedOutFiles = window.x = [];
// Promise, returns collection with all sites
return SiteService.getAllSites().then(sites => {
// For each site get lists then get items matching filter
var promises = [];
sites.forEach(function (site) {
var web = new $pnp.Web(site.url);
promises.push(web.lists
.filter("BaseTemplate eq 101")
.get() // Returns promise with all lists matching filter
.then(lists => {
// Go through each list and find matching item
var promises2 = [];
lists.forEach(function (list) {
promises2.push(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);
// propagate error
throw e;
}));
});
return Promise.all(promises2);
}).catch(e => {
console.log(e);
// propagate error
throw e;
}));
}, this);
return Promise.all(promises).then(() => {
// make checkedOutFiles by the final resolve value
return checkedOutFiles;
});
});
};
// Returns promise with all checkedout file
getCheckedOutFiles().then(files => {
console.log("RESULTS", files);
}).catch(err => {
// handle error here
});
这可以通过在Bluebird promise库中使用Promise.map()
来简化,它会迭代一个数组,调用一个promise产生函数并等待所有的promises完成(.each()
和Promise.all()
)。