Do / Пока XMLHttpRequest добавляет результаты всех вызовов в один массив - PullRequest
1 голос
/ 31 января 2020

Мне нужно l oop на N страницах, используя тег, подобный &page=N, получить указанные идентификаторы c с этих страниц и в конце добавить значения, отсутствующие в окончательном массиве, хранящемся у объекта в локальном хранилище.

Поскольку может быть более ста или более страниц, я не могу просто выполнить For или Do / While l oop, поскольку все запросы будут выполняться одновременно, что приведет к перегрузке сервера.

В любом случае, я нашел решение, которое ожидает выполнения одного запроса, прежде чем запустить другой. Он работает, как и ожидалось (однако я считаю, что это огромный обходной путь, а не хорошее решение).

Проблема заключается в том, что я хотел бы, чтобы каждый запрос преобразовывал массив результатов в «мастер-массив» всех результатов. со всех страниц, которые я хотел бы сравнить с тем, что находится в локальном хранилище, только после выполнения всех запросов. И это не происходит ... Будет ли больше смысла делать это по запросу?

Вот код:

function getUserRatings() {
    storage.get("userID", function(result) {
        if (!isEmpty(result)) {
            var pageNo = 1
            var finalArr = [];
            do {
                (function(cntr) {
                    let resp = requestRatings("https://www.page.com/user/" + result["userID"] + "/info/page-" + pageNo.toString() + "/");
                    resp.then((successMessage) => {
                        finalArr.concat(successMessage);
                        console.log("requestJSON(JSONURL) finished ", successMessage);
                        console.log("finalArr ongoing = ", finalArr);
                    });
                    pageNo++;
                })(pageNo);
            }
            while (pageNo <= 7); // temporary - need to replace this with sth like 'while any of the values in the returned array are not found in local storage array
        }
    });
}

function requestRatings(url) {
    console.log("requesting ratings");
    return new Promise(function (resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open('get', url);
        //xhr.setRequestHeader('Content-Type', 'application/json');
        xhr.onload = function () {
            var status = xhr.status;
            if (status == 200) {
                var rspns = xhr.responseText;
                var doc = new DOMParser().parseFromString(rspns, "text/html");
                //console.log(doc);
                var ratedList = doc.querySelectorAll('a[class~="specificClass"]');
                var arr = Array.prototype.map.call(ratedList, function (e) {return e.getAttribute('href').replace(/(?:.*?stuff\/|-[^$]+)/gm, '')});
                //console.log(arr);
                resolve(arr);
            } else {
                reject(status);
            }
        };
        xhr.send();
    });
}

То, что я считаю обходной частью, это function(cntr) и это, как я подозреваю, также является причиной проблемы с массивом, который не является конкаталированным.

Несмотря на то, что переменная finalArr объявлена ​​вне do / while l oop, она не обновляется (возможно, потому что concat происходит в отдельной функции?).

.

Вот полное решение, которое я хотел бы достичь:

  • L oop просматривая страницы одну за другой, чтобы не перегружать сервер
  • Захват массива, который возвращает запрос
  • Если какое-либо из значений в возвращенном массиве уже существует в массиве, сохраненном в локальном хранилище, прекратить зацикливание (данные на странице отсортированы, поэтому, если я сталкиваюсь с существующим значением, это означает, что все значения после этого уже сохранены и больше не нуждаются в очистке)
  • Concat возвращенного значения массивы в основной массив * 103 0 *
  • Удалить значения из мастер-массива, которые уже находятся в локальном массиве хранения
  • Добавить обновленный мастер-массив в локальный массив хранения

РЕДАКТИРОВАТЬ: я понял, как делать http запросы по одному. К сожалению, запросы не выполняются последовательно. Есть идеи как сделать так?

1 Ответ

0 голосов
/ 02 февраля 2020

Я нашел это, которое помогло мне с последовательными http-запросами - рекурсия - { ссылка }.

Как настроить это:

  • Загрузить сначала страница, получить ответ
  • Получить требуемый массив идентификаторов из ответа
  • Конкатенировать массив идентификаторов с массивом хранения
  • Удалить дубликаты (это на время после того, как все Идентификаторы сохранены, и я снова проверяю первую страницу (с новейшими идентификаторами)
  • сохранить ее в локальном хранилище
  • Если ни один из идентификаторов в массиве отсутствует в массиве хранения, затем снова вызвать функцию изнутри функции с номером страницы +1
...