Когда событие запускается, добавьте запрос, который должен быть сделан, в список и проверьте, можете ли вы сделать запрос, проверив, истинна ли переменная логического флага, которая изначально имеет значение true. Если вы можете сделать запрос, установите для переменной логического флага значение false и go впереди с запросом, иначе никаких действий не требуется.
После завершения запроса проверьте, есть ли какие-либо ожидающие запросы в списке , если есть, то отправляйте эти запросы один за другим. Если нет ожидающих запросов, установите для переменной логического флага значение true, указывающее, что все ожидающие запросы были выполнены.
Пример:
См. Следующий пример, который извлекает случайные шутки из шуток Чака-Норриса api. При первом нажатии кнопки извлечения первый запрос выполняется через 2 секунды. Если вы нажмете кнопку несколько раз до того, как будет сделан первый запрос, все эти запросы будут добавлены в массив pendingRequests
, а после завершения первого запроса будут выполняться следующие запросы, если есть какие-либо ожидающие запросы.
PS setTimeout
добавлено только для того, чтобы показать, что при многократном нажатии кнопки запросы добавляются в массив pendingRequests
. Вы можете удалить это в своем коде, если последуете этому примеру.
const btn = document.querySelector('button');
const baseURL = 'https://api.chucknorris.io/jokes/random';
const pendingRequests = [];
let canMakeRequest = true;
btn.addEventListener('click', getData);
function getData() {
pendingRequests.push(baseURL);
if (canMakeRequest) {
canMakeRequest = false;
setTimeout(() => {
makeRequest(pendingRequests.shift());
}, 2000);
}
}
function makeRequest(url) {
fetch(url)
.then(res => res.json())
.then(data => {
displayData([data]);
const nextURL = pendingRequests.shift();
if (nextURL) {
makeRequest(nextURL);
}
else {
canMakeRequest = true;
}
})
.catch(error => console.log(error));
}
function displayData(data) {
const div = document.querySelector('div');
let html = '';
data.forEach(d => html += `<span>${d.value}</span>`);
div.innerHTML += html;
}
div {
display: flex;
flex-direction: column;
align-items: center;
}
span {
background: #f8f8f8;
box-shadow: 0 0 2px rgba(0, 0, 0, 0.2);
padding: 15px;
margin: 5px;
width: 100%;
text-align: center;
}
<button>Fetch Data</button>
<div id="container"></div>