Skip to content

Instantly share code, notes, and snippets.

@diloabininyeri
Created January 23, 2025 19:45
Show Gist options
  • Save diloabininyeri/fb1297b30dd456a9c53c7ada20d902ed to your computer and use it in GitHub Desktop.
Save diloabininyeri/fb1297b30dd456a9c53c7ada20d902ed to your computer and use it in GitHub Desktop.
an example async and promise simulate
<?php
class Promise
{
private array $callbacks = [];
private array $rejectedCallbacks = [];
/**
* @param Closure $closure
*/
public function __construct(private readonly Closure $closure)
{
($this->closure)($this->resolve(...), $this->reject(...));
}
/**
* @param $value
* @return void
*/
public function resolve($value): void
{
foreach ($this->callbacks as $callback) {
$callback($value);
}
}
/**
* @param $reason
* @return void
*/
public function reject($reason): void
{
foreach ($this->rejectedCallbacks as $callback) {
$callback($reason);
}
}
public function catch(callable $callback): self
{
$this->rejectedCallbacks[] = $callback;
return $this;
}
/**
* @param callable $onFulfilled
* @return Promise
*/
public function then(callable $onFulfilled): self
{
$this->callbacks[] = $onFulfilled;
return $this;
}
}
class Loop
{
private array $callbacks = [];
private static ?self $loop = null;
/**
* @param callable $callback
* @return void
*/
public function addCallback(callable $callback): void
{
$this->callbacks[] = $callback;
}
/**
* @return void
*/
public function run(): void
{
while ($callback = array_shift($this->callbacks)) {
$callback();
}
}
public static function new(): self
{
return static::$loop ??= new static();
}
}
function async(Closure $closure): Promise
{
return new Promise(function ($resolve, $reject) use ($closure) {
Loop::new()->addCallback(function () use ($resolve, $reject, $closure) {
try {
$closure($resolve, $reject);
} catch (\Throwable $e) {
$reject($e->getMessage());
}
});
});
}
async(static function ($resolve) {
return $resolve('success');
})->then(function ($value) {
echo $value . PHP_EOL;
})->catch(function ($reason) {
echo 'Error: ' . $reason . PHP_EOL;
});
async(static function ($resolve, $reject) {
if ((int)date('Y') === 2201) {
return $resolve('happy holidays!');
}
return $reject('failed');
})->then(function ($value) {
echo $value . PHP_EOL;
})->catch(function ($error) {
echo 'Error: ' . $error . PHP_EOL;
});
Loop::new()->run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment