Created
January 23, 2025 19:45
-
-
Save diloabininyeri/fb1297b30dd456a9c53c7ada20d902ed to your computer and use it in GitHub Desktop.
an example async and promise simulate
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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