https://github.com/muqsit/asynciterator
A virion that simplifies writing tasks that traverse iterators
https://github.com/muqsit/asynciterator
api4 async pm4 pmmp virion
Last synced: 3 months ago
JSON representation
A virion that simplifies writing tasks that traverse iterators
- Host: GitHub
- URL: https://github.com/muqsit/asynciterator
- Owner: Muqsit
- License: gpl-3.0
- Created: 2021-03-03T06:23:00.000Z (almost 5 years ago)
- Default Branch: pm5
- Last Pushed: 2024-01-17T11:55:28.000Z (almost 2 years ago)
- Last Synced: 2025-08-26T02:52:25.725Z (4 months ago)
- Topics: api4, async, pm4, pmmp, virion
- Language: PHP
- Homepage: https://poggit.pmmp.io/ci/Muqsit/AsyncIterator
- Size: 31.3 KB
- Stars: 18
- Watchers: 2
- Forks: 5
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# AsyncIterator
`AsyncIterator` simplifies writing asynchronous iteration tasks, such as for-eaching an iterator.
```php
/** @var Plugin $plugin */
$handler = new AsyncIterator($plugin->getScheduler());
```
`AsyncIterator::forEach` traverses forward over an `Iterator` type and notifies handlers in the order of insertion.
Handlers can be added to a `forEach` task by feeding a `Closure` to `AsyncIterator::forEach()::as()`, having the signature `function(TKey $key, TValue $value) : AsyncForeachResult`.
```php
$handler->forEach(new ArrayIterator([1, 2]))
->as(function(int $key, int $value) : AsyncForeachResult{
echo "First ", $value;
return AsyncForeachResult::CONTINUE();
})
->as(function(int $key, int $value) : AsyncForeachResult{
echo "Second ", $value;
return AsyncForeachResult::CONTINUE();
});
```
```
First 1
Second 1
First 2
Second 2
```
By default, `AsyncIterator::forEach` traverses over 10 entries each tick. This can be changed by overriding the default parameter values of the method.
```php
$entries_per_tick = 4;
$sleep_time = 1; // in ticks
AsyncIterator::forEach(new InfiniteIterator(new ArrayIterator([1, 2, 3])), $entries_per_tick, $sleep_time)
->as(function(int $key, int $value) : AsyncForeachResult{
echo $value, ", ";
return AsyncForeachResult::CONTINUE();
});
```
```
# First Tick:
1, 2, 3, 1
# Second Tick:
2, 3, 1, 2
...
```
Completion listeners are triggered when a foreach task successfully completes. This is determined by the return value of `Iterator::valid()` (i.e., `$completed = !Iterator::valid()`) of the iterator that is passed to `AsyncIterator::forEach`.
```php
$handler->forEach(new ArrayIterator([1, 2, 3]))
->as(function(int $key, int $value) : AsyncForeachResult{
echo $value;
return AsyncForeachResult::CONTINUE();
})
->onCompletion(function() : void{ echo "Completed"; })
```
Handlers have the ability to either continue, interrupt or cancel the traversal by returning either `AsyncForeachResult::CONTINUE()`, `AsyncForeachResult::INTERRUPT()` or `AsyncForeachResult::CANCEL()` respectively.
When interrupted, a `forEach` task will not traverse the iterator anymore and notify interrupt listeners immediately.
However, when cancelled, a `forEach` task will notify no listeners and immediately dispose the task away.
```php
$handler->forEach(new ArrayIterator([1, 2, 3]))
->as(function(int $key, int $value) : AsyncForeachResult{
echo $value;
return $value === 2 ? AsyncForeachResult::INTERRUPT() : AsyncForeachResult::CONTINUE();
})
->onCompletion(function() : void{ echo "Completed"; })
->onInterruption(function() : void{ echo "Interrupted"; });
```
```
1
2
Interrupted
```
```php
$handler->forEach(new ArrayIterator([1, 2, 3]))
->as(function(int $key, int $value) : AsyncForeachResult{
echo $value;
return AsyncForeachResult::CONTINUE();
})
->onCompletion(function() : void{ echo "Completed"; })
->onInterruption(function() : void{ echo "Interrupted"; });
```
```
1
2
3
Completed
```
Interruption of a `forEach` task can also occur externally (outside the handler) by calling the `interrupt()` method on the return value of `forEach`.
```php
$foreach_task = $handler->forEach(new ArrayIterator([1, 2, 3]))
->as(function(int $key, int $value) : AsyncForeachResult{
echo $value;
return AsyncForeachResult::CONTINUE();
})
->onCompletion(function() : void{ echo "Completed"; })
->onInterruption(function() : void{ echo "Interrupted"; });
TaskScheduler::scheduleDelayedTask(function() use($foreach_task) : void{
$foreach_task->interrupt();
}, ticks: 2);
```
```
1
2
Interrupted
```
A `forEach` task may be cancelled by calling the `cancel()` method on the return value of `forEach`, causing no interrupt or completion listeners to be notified.
```php
$foreach_task = $handler->forEach(new ArrayIterator([1, 2, 3]))
->as(function(int $key, int $value) : AsyncForeachResult{
echo $value;
return AsyncForeachResult::CONTINUE();
})
->onCompletion(function() : void{ echo "Completed"; })
->onInterruption(function() : void{ echo "Interrupted"; });
TaskScheduler::scheduleDelayedTask(function() use($foreach_task) : void{
$foreach_task->cancel();
}, ticks: 2);
```
```
1
2
```