iterate
(PHP 8.6+, True Async 1.0.0)
iterate() — Iteriert nebenlaeufig ueber ein Array oder Traversable und ruft fuer jedes Element einen callback auf.
Beschreibung
iterate(iterable $iterable, callable $callback, int $concurrency = 0, bool $cancelPending = true): void
Fuehrt callback fuer jedes Element von iterable in einer separaten Coroutine aus.
Der Parameter concurrency ermoeglicht die Begrenzung der Anzahl gleichzeitig laufender Callbacks.
Die Funktion blockiert die aktuelle Coroutine, bis alle Iterationen abgeschlossen sind.
Alle ueber iterate() gestarteten Coroutinen laufen in einem isolierten Kind-Scope.
Parameter
iterable
Ein Array oder ein Objekt, das Traversable implementiert (einschliesslich Generatoren und ArrayIterator).
callback
Eine Funktion, die fuer jedes Element aufgerufen wird. Akzeptiert zwei Argumente: (mixed $value, mixed $key).
Wenn der Callback false zurueckgibt, wird die Iteration gestoppt.
concurrency
Maximale Anzahl gleichzeitig laufender Callbacks. Standard ist 0 — das Standardlimit,
alle Elemente werden nebenlaeufig verarbeitet. Ein Wert von 1 bedeutet Ausfuehrung in einer einzelnen Coroutine.
cancelPending
Steuert das Verhalten von Kind-Coroutinen, die innerhalb des Callbacks (ueber spawn()) gestartet wurden, nachdem die Iteration abgeschlossen ist.
true(Standard) — alle nicht beendeten gestarteten Coroutinen werden mitAsyncCancellationabgebrochen.false—iterate()wartet auf den Abschluss aller gestarteten Coroutinen, bevor es zurueckkehrt.
Rueckgabewerte
Die Funktion gibt keinen Wert zurueck.
Fehler/Ausnahmen
Error— wenn ausserhalb eines asynchronen Kontexts oder aus dem Scheduler-Kontext aufgerufen.TypeError— wenniterablekein Array ist undTraversablenicht implementiert.- Wenn der Callback eine Ausnahme wirft, wird die Iteration gestoppt, verbleibende Coroutinen werden abgebrochen und die Ausnahme wird an den aufrufenden Code weitergegeben.
Beispiele
Beispiel #1 Grundlegende Array-Iteration
<?php
use function Async\spawn;
use function Async\iterate;
spawn(function() {
$urls = [
'php' => 'https://php.net',
'github' => 'https://github.com',
'google' => 'https://google.com',
];
iterate($urls, function(string $url, string $name) {
$content = file_get_contents($url);
echo "$name: " . strlen($content) . " Bytes\n";
});
echo "Alle Anfragen abgeschlossen\n";
});
?>
Beispiel #2 Nebenlaeufigkeit begrenzen
<?php
use function Async\spawn;
use function Async\iterate;
spawn(function() {
$userIds = range(1, 100);
// Maximal 10 Benutzer gleichzeitig verarbeiten
iterate($userIds, function(int $userId) {
$data = file_get_contents("https://api.example.com/users/$userId");
echo "Benutzer $userId geladen\n";
}, concurrency: 10);
echo "Alle Benutzer verarbeitet\n";
});
?>
Beispiel #3 Iteration per Bedingung stoppen
<?php
use function Async\spawn;
use function Async\iterate;
spawn(function() {
$items = ['apple', 'banana', 'cherry', 'date', 'elderberry'];
iterate($items, function(string $item) {
echo "Verarbeite: $item\n";
if ($item === 'cherry') {
return false; // Iteration stoppen
}
});
echo "Iteration beendet\n";
});
?>
Ausgabe:
Verarbeite: apple
Verarbeite: banana
Verarbeite: cherry
Iteration beendet
Beispiel #4 Ueber einen Generator iterieren
<?php
use function Async\spawn;
use function Async\iterate;
function generateTasks(): Generator {
for ($i = 1; $i <= 5; $i++) {
yield "task-$i" => $i;
}
}
spawn(function() {
iterate(generateTasks(), function(int $value, string $key) {
echo "$key: Verarbeite Wert $value\n";
}, concurrency: 2);
echo "Alle Aufgaben abgeschlossen\n";
});
?>
Beispiel #5 Gestartete Coroutinen abbrechen (cancelPending = true)
Standardmaessig werden ueber spawn() innerhalb des Callbacks gestartete Coroutinen nach Abschluss der Iteration abgebrochen:
<?php
use function Async\spawn;
use function Async\iterate;
use Async\AsyncCancellation;
spawn(function() {
iterate([1, 2, 3], function(int $value) {
// Hintergrundaufgabe starten
spawn(function() use ($value) {
try {
echo "Hintergrundaufgabe $value gestartet\n";
suspend();
suspend();
echo "Hintergrundaufgabe $value beendet\n"; // Wird nicht ausgefuehrt
} catch (AsyncCancellation) {
echo "Hintergrundaufgabe $value abgebrochen\n";
}
});
});
echo "Iteration beendet\n";
});
?>
Ausgabe:
Hintergrundaufgabe 1 gestartet
Hintergrundaufgabe 2 gestartet
Hintergrundaufgabe 3 gestartet
Hintergrundaufgabe 1 abgebrochen
Hintergrundaufgabe 2 abgebrochen
Hintergrundaufgabe 3 abgebrochen
Iteration beendet
Beispiel #6 Auf gestartete Coroutinen warten (cancelPending = false)
Wenn Sie cancelPending: false uebergeben, wartet iterate() auf den Abschluss aller gestarteten Coroutinen:
<?php
use function Async\spawn;
use function Async\iterate;
spawn(function() {
$results = [];
iterate([1, 2, 3], function(int $value) use (&$results) {
// Hintergrundaufgabe starten
spawn(function() use (&$results, $value) {
suspend();
$results[] = "result-$value";
});
}, cancelPending: false);
// Alle Hintergrundaufgaben sind abgeschlossen
sort($results);
echo implode(', ', $results) . "\n";
});
?>
Ausgabe:
result-1, result-2, result-3
Beispiel #7 Fehlerbehandlung
<?php
use function Async\spawn;
use function Async\iterate;
spawn(function() {
try {
iterate([1, 2, 3, 4, 5], function(int $value) {
if ($value === 3) {
throw new RuntimeException("Fehler bei der Verarbeitung von Element $value");
}
echo "Verarbeitet: $value\n";
});
} catch (RuntimeException $e) {
echo "Abgefangen: " . $e->getMessage() . "\n";
}
});
?>
Hinweise
Hinweis:
iterate()erstellt einen isolierten Kind-Scope fuer alle gestarteten Coroutinen.
Hinweis: Wenn ein Array uebergeben wird, erstellt
iterate()vor der Iteration eine Kopie davon. Das Aendern des urspruenglichen Arrays innerhalb des Callbacks beeinflusst die Iteration nicht.
Hinweis: Wenn der
callbackfalsezurueckgibt, wird die Iteration gestoppt, aber bereits laufende Coroutinen werden bis zum Abschluss fortgesetzt (oder abgebrochen, wenncancelPending = true).
Changelog
| Version | Beschreibung |
|---|---|
| 1.0.0 | Funktion iterate() hinzugefuegt. |
Siehe auch
- spawn() - Starten einer Coroutine
- await_all() - Warten auf mehrere Coroutinen
- Scope - Das Scope-Konzept
- Cancellation - Coroutine-Abbruch