我正在使用SharePoint进行JSOM调用。我需要获取结果,并且在获取所有数据之前不要继续前进。我已经尝试了很多示例(没有一个完整的示例足以使我了解如何使用嵌套的$ .each循环语句来解决我的问题。我似乎已经接近了,但是从来没有任何正常工作。
我已经编辑了我的实际代码(减去了从另一个页面传入的前3个变量),以合并Tomalak的工作,以便我们可以更好地弄清楚。当前,结果是空对象。试图弄清楚我做错了什么。
[编辑于2018年8月6日] 终于让它工作了。我发现提供的代码只有两个小问题:-)。我会尝试加粗它们。
var fya = [2008,2009]; //Fiscal Year Array which we use to know what lists to look at
var assignedRecords = []; //Global Reusable Variable
var assignedCourses = ['Math','Science','Reading']; //There might not be records who are associated with a particular course in each list. Wee need to pull the student records (assignedRecords) assoiciated with the above in 2008 and 2009.
SP.ClientContext.prototype.executeQueryPromise = function (items) {
var result = $.Deferred();
this.load(items);
this.executeQueryAsync(function (sender, args) { result.resolve(items) },
function (sender, args) { result.reject(args) });
return result.promise();
};
移动'var arr = [];'在arrayFromCollection之外 在同一函数中将'var'添加到e变量
var arr = [];
function arrayFromCollection(coll) {
var e = coll.getEnumerator();
while (e.moveNext()) arr.push(e.get_current());
return arr;
};
function queryListPromise(title, course) {
var list = hostWeb.get_lists().getByTitle(title);
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml('<View><Query><Where>'
+ '<Eq><FieldRef Name="Course"/><Value Type="Text">' + course + '</Value></Eq>'
+ '</Where></Query></View>');
return context.executeQueryPromise(list.getItems(camlQuery)).then(arrayFromCollection);
};
function GetAssignedApplications() {
assignedRecords = []; //Need to start empty
var myCourses = assignedCourses;
$.each(myCourses, function (i, myCoursesItem) {
var courseName = myCoursesItem.get_lookupValue();
将“ $ .forEach”更改为“ $ .each”
$.each(fya, function (n, fyaItem) {
var listTitle = "FY" + String(fyaItem).substring(2); //FY18 & FY19 are the names of the actual lists.
assignedRecords.push(queryListPromise(listTitle, courseName));
});
});
$.when(assignedRecords).then(function (results) {
return Array.prototype.concat.apply([], results);
}).then(function (items) {
items.forEach(function (item) {
var a = item; //item is empty and this actually runs before arrayFromCollection and it returns duplicate records (4) when there is only 2.
});
}).fail(onError);
};
答案 0 :(得分:0)
因此首先,$.when()
完成了在jQuery中等待多个promise。
$.when(p1, p2, p3).then(function (results) {
// results is an array of length 3
});
为了通过可变的参数计数实现此目的,我们使用Function#apply
:
var promises = [p1, p2, p3]; // could be be of any length now
$.when.apply($, promises).then(function () {
var results = [].slice.call(arguments);
// results is an array of the same length as promises
});
为了使其可重用,我们将其称为$.whenAll
:
$.whenAll = function (promises) {
return $.when.apply($, promises).then(function () {
return [].slice.call(arguments);
});
};
现在我们可以做到:
$.whenAll([p1, p2, p3]).then(function (results) {
// results is an array of length 3
});
接下来,我们需要将基于回调的executeQueryAsync()
转换为基于Promise的函数。通常,承诺遵循以下方案:
function somethingPromise(args) {
var result = $.Deferred();
somethingAsync(/* onSuccess */ result.resolve, /* onError */ result.reject);
return result.promise();
}
这期望onSuccess和onError处理程序将数据作为参数接收。 executeQueryAsync
并非如此-它直接修改items
。但是,我们仍然想用items
来解决诺言,因此我们需要明确地做到这一点。
让我们立即将其拍打到SP.ClientContext
原型上以重新使用。
SP.ClientContext.prototype.executeQueryPromise = function (items) {
var result = $.Deferred();
this.load(items);
this.executeQueryAsync(
function (sender, args) { result.resolve(items); },
function (sender, args) { result.reject(args); }
);
return result.promise();
};
接下来,我们应该建立一个助手,将那些笨拙的收藏集变成有用的东西。
function arrayFromCollection(coll) {
var arr = [], e = coll.getEnumerator();
while (e.moveNext()) arr.push(e.get_current());
return arr;
}
完成所有操作后,我们可以提取一个函数,该函数带有标题并为项目数组返回promise。
function queryListPromise(title) {
var list = web.get_lists().getByTitle(title);
var q = new SP.CamlQuery();
//...
return ctx.executeQueryPromise(list.getItems(q)).then(arrayFromCollection);
}
最后,由于您想要一个简单的项目列表,因此我们应该从一个简单的查询列表开始:
function GetNextFunction() {
var queries = [];
// build flat list of queries
$.each(arr1, function(i, arr1Item) {
$.each(arr2, function(n, arr2Item) {
queries.push(queryListPromise(arr2Item));
});
});
// wait on all queries
$.whenAll(queries).then(function (results) {
// flatten incoming array of arrays
return Array.prototype.concat.apply([], results);
}).then(function (items) {
// items contains all items from all queries
items.forEach(function (item) { /* ... */ });
}).fail(onError);
}
这里queries
变成了承诺的平面数组,每个承诺都将解析为一组项目。因此,results
将是一组由项目组成的数组。