Lekcje modułu (4/4)
Wyzwanie: planowanie z obietnicami
„Scheduling” (harmonogramowanie) oznacza decydowanie o tym, jak wykonać listę zadań asynchronicznych:
wszystkie na raz, jedno po drugim lub w małych grupach. Połączimy w tym celu Promise.all, for await
oraz closures.
Równolegle: Wszystko razem
Gdy zadania są niezależne i szybkie, uruchom je wszystkie na raz i oczekuj na nie za pomocą Promise.all:
async function inParallelo(tasks) {
return Promise.all(tasks.map((t) => t()));
}
const risultati = await inParallelo([
() => Promise.resolve(1),
() => Promise.resolve(2),
() => Promise.resolve(3),
]);
// [1, 2, 3]Czas całkowity ≈ czas najwolniejszego zadania.
Sekwencyjnie: Jedno po drugim
Gdy każde zadanie zależy od poprzedniego lub chcesz zastosować rate-limit (ograniczenie liczby żądań):
async function inSerie(tasks) {
const risultati = [];
for (const t of tasks) {
risultati.push(await t());
}
return risultati;
}Czas całkowity ≈ suma czasów poszczególnych zadań.
Z limitem współbieżności (Concurrency Limit)
Czasami nie chcesz wysyłać tysiąca żądań na raz, ale też nie chcesz czekać na nie sekwencyjnie: chcesz mieć maksymalnie N zadań aktywnych w tym samym czasie.
async function conLimite(tasks, n) {
const risultati = new Array(tasks.length);
let i = 0;
async function worker() {
while (i < tasks.length) {
const mio = i++;
risultati[mio] = await tasks[mio]();
}
}
await Promise.all(Array.from({ length: n }, worker));
return risultati;
}Idea: uruchamiasz n procesów roboczych („workers”), które pobierają kolejny indeks, dopóki zadania się nie skończą.
Spróbuj sam
Zdefiniuj funkcję asynchroniczną `inSeries(tasks)`: dla danej tablicy funkcji zwracających obietnice, wykonuj je pojedynczo (await) i zwróć tablicę wyników w kolejności ich wykonywania.
Pokaż wskazówkę
for ... of e push(await t())
Rozwiązanie dostępne po 3 próbach
Ćwiczenie powtórzeniowe
Zdefiniuj funkcję asynchroniczną `inParallel(tasks)`: dla danej tablicy funkcji zwracających obietnice, uruchom wszystkie równolegle i zwróć tablicę wyników w tej samej kolejności co dane wejściowe. Użyj Promise.all.
Pokaż wskazówkę
Promise.all(tasks.map((t) => t()))
Rozwiązanie dostępne po 3 próbach