Для имитации запускайте задачи последовательно через await, измеряйте их длительность и обновляйте число выполненных запросов. Повторный Start блокируйте до завершения.
UI‑компонент для имитации последовательных HTTP‑запросов с пользовательскими параметрами
Для имитации запускайте задачи последовательно через await, измеряйте их длительность и обновляйте число выполненных запросов. Повторный Start блокируйте до завершения.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
В примере реализован простой React‑компонент, который выводит форму с полями ввода URL‑адреса, количества запросов, среднего времени ответа и количества уже выполненных запросов. Кнопка «Start» пока не содержит обработчика, но служит точкой входа для дальнейшей логики.
import React from "react";
export function App() {
const [numOfRequests] = React.useState(10);
const [url] = React.useState("codesandbox.io");
return (
<div>
<div>
<label>URL</label>
<input value={url} />
</div>
<div>
<label>Number of requests</label>
<input value={numOfRequests} />
</div>
<div>
<label>Avg response time</label>
<input />
</div>
<div>
<label>Requests made</label>
<input />
</div>
<button>Start</button>
</div>
);
}
Ответ
Для имитации запускайте задачи последовательно через await, измеряйте их длительность и обновляйте число выполненных запросов. Повторный Start блокируйте до завершения.
Этот пример не обращается к введённому сайту, а имитирует задержку:
function App() {
const [url, setUrl] = React.useState('https://example.com');
const [amount, setAmount] = React.useState('10');
const [stats, setStats] = React.useState({ count: 0, total: 0 });
const [busy, setBusy] = React.useState(false);
const active = React.useRef(false);
const run = React.useRef(0);
React.useEffect(() => () => { run.current++; }, []);
async function start() {
const count = Number(amount);
if (active.current || !Number.isInteger(count) || count < 1 || count > 100) return;
active.current = true; setBusy(true); setStats({ count: 0, total: 0 });
const token = ++run.current;
let total = 0;
for (let index = 0; index < count; index++) {
const began = performance.now();
await new Promise(resolve => setTimeout(resolve, 50));
if (run.current !== token) return;
total += performance.now() - began;
setStats({ count: index + 1, total });
}
active.current = false; setBusy(false);
}
return <div>
<label>URL <input value={url} disabled={busy} onChange={e => setUrl(e.target.value)} /></label>
<label>Number of requests <input type='number' min='1' max='100' value={amount} disabled={busy} onChange={e => setAmount(e.target.value)} /></label>
<p>Avg response time: {stats.count ? (stats.total / stats.count).toFixed(1) : 0} мс</p>
<p>Requests made: {stats.count}</p>
<button disabled={busy} onClick={start}>Start</button>
</div>;
}
Для настоящей загрузки вместо задержки нужен fetch с проверкой статуса, отменой и согласованным лимитом. Не превращайте демонстрацию в неконтролируемую нагрузку на произвольный URL.