Вопрос или проблема
Я хочу получить все элементы из списка SharePoint. В списке более 5000 элементов, поэтому нужен рекурсивный ajax вызов REST-API. Я могу загрузить все данные в массив, но код, который вызывает Ajax функции, похоже, ничего не делает в .then()
, посмотрите мой код ниже. Я, кажется, упускаю очевидное.
var url = _spPageContextInfo.webServerRelativeUrl + "/_api/web/lists/getbytitle('LISTNAME')/items?$select=ID,Title,TEST,LINK,Modified,Editor/Title&$top=5000&$expand=Editor/Id";
function getAllItemsFromList(url) {
return new Promise((resolve, reject) => {
$.ajax({
url: url,
method: "GET",
dataType: "json",
headers: {
"Accept": "application/json; odata=verbose"
},
}).done(function (data) {
if (data.d.__next) {
console.log("true: ", data.d.results);
url = data.d.__next;
data.d.results.forEach(element => {
all_items_from_list.push(element);
});
getAllItemsFromList(url);
}
else {
console.log("false: ", data.d.results);
data.d.results.forEach(element => {
all_items_from_list.push(element);
});
//выводит все 7345 элементов в консоль
console.log("false, all_items_from_list: ", all_items_from_list);
resolve("yay");
}
}).fail(function () {
console.log("это пошло ужасно не так!");
reject("ERROR!");
});
});
};
var all_items_from_list = [];
getAllItemsFromList(url).then(
function (value) { console.log("Я здесь и получил следующие данные: ", all_items_from_list) },
function (error) { /* код на случай ошибки */ }
);
Я получаю следующий вывод:
true: Array(5000)
false: Array(2346)
false, all_items_from_list: Array(7346)
Я нашел решение, просто не хватало async
и await
… иногда немного свежего воздуха помогает.
async function getAllItemsFromList(url) {
await $.ajax({
url: url,
method: "GET",
dataType: "json",
headers: {
"Accept": "application/json; odata=verbose"
},
}).done(function (data) {
if (data.d.__next) {
url = data.d.__next;
data.d.results.forEach(element => {
all_items_from_list.push(element);
});
getAllItemsFromList(url);
} else {
data.d.results.forEach(element => {
all_items_from_list.push(element);
});
}
}).fail(function () {
console.log("Не удалось получить все данные!");
});
};
```
Ответ или решение
Рекурсивный AJAX-вызов с использованием jQuery и SharePoint для получения всех элементов из списка SharePoint
Вопрос, который вы подняли, крайне актуален для разработчиков и IT-специалистов, работающих с SharePoint, особенно в условиях, когда количество элементов в списке превышает лимит в 5000 элементов. В данной статье мы подробно рассмотрим, как можно получить все элементы из списка SharePoint, используя рекурсивные AJAX-вызовы с помощью jQuery, а также обратим внимание на важные техники, такие как использование async
и await
для управления асинхронностью.
Проблема
Ваша исходная реализация уже содержит необходимые элементы для выполнения задачи. Вы используете AJAX-запросы для получения данных из REST API SharePoint, но вы столкнулись с некоторыми трудностями при использовании промисов и управления асинхронностью. Ваша функция getAllItemsFromList
должна возвращать массив всех элементов, но вы отмечаете, что вывод результата не соответствовал ожиданиям.
Решение
При работе с асинхронными вызовами важно корректно обрабатывать последовательность операций. Ваша ошибка заключалась в том, что рекурсивные вызовы функции не дожидались завершения работы предыдущего вызова. Решением данной проблемы является использование async
и await
, что позволяет кодировать асинхронные операции более линейно и избежать вложенности.
Пример кода
Вот обновленная версия вашей функции с использованием async
и await
:
var url = _spPageContextInfo.webServerRelativeUrl + "/_api/web/lists/getbytitle('LISTNAME')/items?$select=ID,Title,TEST,LINK,Modified,Editor/Title&$top=5000&$expand=Editor/Id";
async function getAllItemsFromList(url) {
try {
const data = await $.ajax({
url: url,
method: "GET",
dataType: "json",
headers: {
"Accept": "application/json; odata=verbose"
},
});
data.d.results.forEach(element => {
all_items_from_list.push(element);
});
// Проверка наличия следующего набора данных
if (data.d.__next) {
await getAllItemsFromList(data.d.__next);
}
} catch (error) {
console.error("Произошла ошибка: ", error);
}
}
var all_items_from_list = [];
getAllItemsFromList(url).then(() => {
console.log("Полученные данные: ", all_items_from_list);
});
Объяснение кода
-
Асинхронная функция
getAllItemsFromList
: Использованиеasync
перед определением функции позволяет нам использоватьawait
внутри функции. Это помогает нам дожидаться результата AJAX-запроса, прежде чем продолжить выполнение. -
try-catch
блок: Помогает управлять ошибками, возникающими при выполнении AJAX-запросов. Это особенно важно в средах, где сеть может быть ненадежной. -
Проверка на наличие следующего набора данных: Если
data.d.__next
существует, это означает, что в списке есть больше данных для обработки. В этом случае вызывается рекурсивно сама функция, передавая новый URL. -
Заключительное предоставление данных: После завершения всех рекурсивных запросов выводится полный массив полученных данных, доступный для дальнейшей обработки.
Заключение
При работе с SharePoint и обработкой больших списков, рекурсивные AJAX-вызовы требуют внимательной настройки асинхронных операций. Использование async
и await
значительно упрощает управление потоками выполнения, что, в свою очередь, позволяет избежать потенциальных ошибок и некорректной обработки данных. Следуя приведенному примеру, вы теперь можете эффективно получать все элементы из списка SharePoint, независимо от их количества.