/**
* Creates a new fiber asynchronously using the given closure, returning a Future that is completed with the
* eventual return value of the passed function or will fail if the closure throws an exception.
*
* @template T
*
* @param \Closure(...):T $closure
* @param mixed ...$args Arguments forwarded to the closure when starting the fiber.
*
* @return Future<T>
*/
function async(\Closure $closure, mixed ...$args): Future
{
static $run = null;
// 这里 ??=
$run ??= static function (FutureState $state, \Closure $closure, array $args): void {
$s = $state;
$c = $closure;
/* Null function arguments so an exception thrown from the closure does not contain the FutureState object
* in the stack trace, which would create a circular reference, preventing immediate garbage collection */
$state = $closure = null;
try {
// Clear $args to allow garbage collection of arguments during fiber execution
$s->complete($c(...$args, ...($args = [])));
} catch (\Throwable $exception) {
$s->error($exception);
}
};
$state = new Internal\FutureState;
EventLoop::queue($run, $state, $closure, $args);
return new Future($state);
}
大概功能就是如果$run 变量存在则使用原来的变量 如果变量不存在则给$run 变量赋值
null运算合并符
??= 空赋值运算符 php版本>=7.4才可以
防御性编程的典范
省了if判断null,不过还是最low的写法好,因为兼容更多