Commit inicial con archivos existentes
This commit is contained in:
256
vendor/react/promise/src/Promise.php
vendored
Executable file
256
vendor/react/promise/src/Promise.php
vendored
Executable file
@@ -0,0 +1,256 @@
|
||||
<?php
|
||||
|
||||
namespace React\Promise;
|
||||
|
||||
class Promise implements ExtendedPromiseInterface, CancellablePromiseInterface
|
||||
{
|
||||
private $canceller;
|
||||
private $result;
|
||||
|
||||
private $handlers = [];
|
||||
private $progressHandlers = [];
|
||||
|
||||
private $requiredCancelRequests = 0;
|
||||
private $cancelRequests = 0;
|
||||
|
||||
public function __construct(callable $resolver, callable $canceller = null)
|
||||
{
|
||||
$this->canceller = $canceller;
|
||||
|
||||
// Explicitly overwrite arguments with null values before invoking
|
||||
// resolver function. This ensure that these arguments do not show up
|
||||
// in the stack trace in PHP 7+ only.
|
||||
$cb = $resolver;
|
||||
$resolver = $canceller = null;
|
||||
$this->call($cb);
|
||||
}
|
||||
|
||||
public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
|
||||
{
|
||||
if (null !== $this->result) {
|
||||
return $this->result->then($onFulfilled, $onRejected, $onProgress);
|
||||
}
|
||||
|
||||
if (null === $this->canceller) {
|
||||
return new static($this->resolver($onFulfilled, $onRejected, $onProgress));
|
||||
}
|
||||
|
||||
// This promise has a canceller, so we create a new child promise which
|
||||
// has a canceller that invokes the parent canceller if all other
|
||||
// followers are also cancelled. We keep a reference to this promise
|
||||
// instance for the static canceller function and clear this to avoid
|
||||
// keeping a cyclic reference between parent and follower.
|
||||
$parent = $this;
|
||||
++$parent->requiredCancelRequests;
|
||||
|
||||
return new static(
|
||||
$this->resolver($onFulfilled, $onRejected, $onProgress),
|
||||
static function () use (&$parent) {
|
||||
if (++$parent->cancelRequests >= $parent->requiredCancelRequests) {
|
||||
$parent->cancel();
|
||||
}
|
||||
|
||||
$parent = null;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function done(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
|
||||
{
|
||||
if (null !== $this->result) {
|
||||
return $this->result->done($onFulfilled, $onRejected, $onProgress);
|
||||
}
|
||||
|
||||
$this->handlers[] = static function (ExtendedPromiseInterface $promise) use ($onFulfilled, $onRejected) {
|
||||
$promise
|
||||
->done($onFulfilled, $onRejected);
|
||||
};
|
||||
|
||||
if ($onProgress) {
|
||||
$this->progressHandlers[] = $onProgress;
|
||||
}
|
||||
}
|
||||
|
||||
public function otherwise(callable $onRejected)
|
||||
{
|
||||
return $this->then(null, static function ($reason) use ($onRejected) {
|
||||
if (!_checkTypehint($onRejected, $reason)) {
|
||||
return new RejectedPromise($reason);
|
||||
}
|
||||
|
||||
return $onRejected($reason);
|
||||
});
|
||||
}
|
||||
|
||||
public function always(callable $onFulfilledOrRejected)
|
||||
{
|
||||
return $this->then(static function ($value) use ($onFulfilledOrRejected) {
|
||||
return resolve($onFulfilledOrRejected())->then(function () use ($value) {
|
||||
return $value;
|
||||
});
|
||||
}, static function ($reason) use ($onFulfilledOrRejected) {
|
||||
return resolve($onFulfilledOrRejected())->then(function () use ($reason) {
|
||||
return new RejectedPromise($reason);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public function progress(callable $onProgress)
|
||||
{
|
||||
return $this->then(null, null, $onProgress);
|
||||
}
|
||||
|
||||
public function cancel()
|
||||
{
|
||||
if (null === $this->canceller || null !== $this->result) {
|
||||
return;
|
||||
}
|
||||
|
||||
$canceller = $this->canceller;
|
||||
$this->canceller = null;
|
||||
|
||||
$this->call($canceller);
|
||||
}
|
||||
|
||||
private function resolver(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
|
||||
{
|
||||
return function ($resolve, $reject, $notify) use ($onFulfilled, $onRejected, $onProgress) {
|
||||
if ($onProgress) {
|
||||
$progressHandler = static function ($update) use ($notify, $onProgress) {
|
||||
try {
|
||||
$notify($onProgress($update));
|
||||
} catch (\Throwable $e) {
|
||||
$notify($e);
|
||||
} catch (\Exception $e) {
|
||||
$notify($e);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
$progressHandler = $notify;
|
||||
}
|
||||
|
||||
$this->handlers[] = static function (ExtendedPromiseInterface $promise) use ($onFulfilled, $onRejected, $resolve, $reject, $progressHandler) {
|
||||
$promise
|
||||
->then($onFulfilled, $onRejected)
|
||||
->done($resolve, $reject, $progressHandler);
|
||||
};
|
||||
|
||||
$this->progressHandlers[] = $progressHandler;
|
||||
};
|
||||
}
|
||||
|
||||
private function reject($reason = null)
|
||||
{
|
||||
if (null !== $this->result) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->settle(reject($reason));
|
||||
}
|
||||
|
||||
private function settle(ExtendedPromiseInterface $promise)
|
||||
{
|
||||
$promise = $this->unwrap($promise);
|
||||
|
||||
if ($promise === $this) {
|
||||
$promise = new RejectedPromise(
|
||||
new \LogicException('Cannot resolve a promise with itself.')
|
||||
);
|
||||
}
|
||||
|
||||
$handlers = $this->handlers;
|
||||
|
||||
$this->progressHandlers = $this->handlers = [];
|
||||
$this->result = $promise;
|
||||
$this->canceller = null;
|
||||
|
||||
foreach ($handlers as $handler) {
|
||||
$handler($promise);
|
||||
}
|
||||
}
|
||||
|
||||
private function unwrap($promise)
|
||||
{
|
||||
$promise = $this->extract($promise);
|
||||
|
||||
while ($promise instanceof self && null !== $promise->result) {
|
||||
$promise = $this->extract($promise->result);
|
||||
}
|
||||
|
||||
return $promise;
|
||||
}
|
||||
|
||||
private function extract($promise)
|
||||
{
|
||||
if ($promise instanceof LazyPromise) {
|
||||
$promise = $promise->promise();
|
||||
}
|
||||
|
||||
return $promise;
|
||||
}
|
||||
|
||||
private function call(callable $cb)
|
||||
{
|
||||
// Explicitly overwrite argument with null value. This ensure that this
|
||||
// argument does not show up in the stack trace in PHP 7+ only.
|
||||
$callback = $cb;
|
||||
$cb = null;
|
||||
|
||||
// Use reflection to inspect number of arguments expected by this callback.
|
||||
// We did some careful benchmarking here: Using reflection to avoid unneeded
|
||||
// function arguments is actually faster than blindly passing them.
|
||||
// Also, this helps avoiding unnecessary function arguments in the call stack
|
||||
// if the callback creates an Exception (creating garbage cycles).
|
||||
if (\is_array($callback)) {
|
||||
$ref = new \ReflectionMethod($callback[0], $callback[1]);
|
||||
} elseif (\is_object($callback) && !$callback instanceof \Closure) {
|
||||
$ref = new \ReflectionMethod($callback, '__invoke');
|
||||
} else {
|
||||
$ref = new \ReflectionFunction($callback);
|
||||
}
|
||||
$args = $ref->getNumberOfParameters();
|
||||
|
||||
try {
|
||||
if ($args === 0) {
|
||||
$callback();
|
||||
} else {
|
||||
// Keep references to this promise instance for the static resolve/reject functions.
|
||||
// By using static callbacks that are not bound to this instance
|
||||
// and passing the target promise instance by reference, we can
|
||||
// still execute its resolving logic and still clear this
|
||||
// reference when settling the promise. This helps avoiding
|
||||
// garbage cycles if any callback creates an Exception.
|
||||
// These assumptions are covered by the test suite, so if you ever feel like
|
||||
// refactoring this, go ahead, any alternative suggestions are welcome!
|
||||
$target =& $this;
|
||||
$progressHandlers =& $this->progressHandlers;
|
||||
|
||||
$callback(
|
||||
static function ($value = null) use (&$target) {
|
||||
if ($target !== null) {
|
||||
$target->settle(resolve($value));
|
||||
$target = null;
|
||||
}
|
||||
},
|
||||
static function ($reason = null) use (&$target) {
|
||||
if ($target !== null) {
|
||||
$target->reject($reason);
|
||||
$target = null;
|
||||
}
|
||||
},
|
||||
static function ($update = null) use (&$progressHandlers) {
|
||||
foreach ($progressHandlers as $handler) {
|
||||
$handler($update);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$target = null;
|
||||
$this->reject($e);
|
||||
} catch (\Exception $e) {
|
||||
$target = null;
|
||||
$this->reject($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user