Рекурсивный AJAX-вызов JQuery и SharePoint для получения всех элементов из списка SharePoint

Вопрос или проблема

Я хочу получить все элементы из списка 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);
});

Объяснение кода

  1. Асинхронная функция getAllItemsFromList: Использование async перед определением функции позволяет нам использовать await внутри функции. Это помогает нам дожидаться результата AJAX-запроса, прежде чем продолжить выполнение.

  2. try-catch блок: Помогает управлять ошибками, возникающими при выполнении AJAX-запросов. Это особенно важно в средах, где сеть может быть ненадежной.

  3. Проверка на наличие следующего набора данных: Если data.d.__next существует, это означает, что в списке есть больше данных для обработки. В этом случае вызывается рекурсивно сама функция, передавая новый URL.

  4. Заключительное предоставление данных: После завершения всех рекурсивных запросов выводится полный массив полученных данных, доступный для дальнейшей обработки.

Заключение

При работе с SharePoint и обработкой больших списков, рекурсивные AJAX-вызовы требуют внимательной настройки асинхронных операций. Использование async и await значительно упрощает управление потоками выполнения, что, в свою очередь, позволяет избежать потенциальных ошибок и некорректной обработки данных. Следуя приведенному примеру, вы теперь можете эффективно получать все элементы из списка SharePoint, независимо от их количества.

Оцените материал
Добавить комментарий

Капча загружается...