Мне нужно 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 запросы по одному. К сожалению, запросы не выполняются последовательно. Есть идеи как сделать так?