defer() публичный статический Метод

The deferred callable MUST be executed in the next tick of the event loop and before any other type of watcher. Order of enabling MUST be preserved when executing the callbacks.
public static defer ( callable $callback, mixed $data = null ) : string
$callback callable
$data mixed Arbitrary data given to the callback function as the `$data` parameter.
Результат string An unique identifier that can be used to cancel, enable or disable the watcher.
Пример #1
0
 public function when(callable $onResolved)
 {
     try {
         $onResolved($this->error);
     } catch (\Throwable $e) {
         Loop::defer(function () use($e) {
             throw $e;
         });
     }
 }
Пример #2
0
 /**
  * {@inheritdoc}
  */
 public function when(callable $onResolved)
 {
     try {
         $onResolved($this->exception, null);
     } catch (\Throwable $exception) {
         Loop::defer(static function () use($exception) {
             throw $exception;
         });
     }
 }
Пример #3
0
 protected function runServer(callable $server, callable $client) : \Generator
 {
     $socket = (yield $this->serverFactory->createSocketServer());
     try {
         return (yield new AwaitAll([new Coroutine($this->serverTask($socket, $server)), new Coroutine($this->clientTask($socket, $client))]));
     } finally {
         Loop::defer(function () use($socket) {
             $socket->close();
         });
     }
 }
Пример #4
0
 /**
  * Calls each callback in the queue, passing the provided values to the function.
  *
  * @param \Throwable|null $exception
  * @param mixed $value
  */
 public function __invoke($exception, $value)
 {
     foreach ($this->queue as $callback) {
         try {
             $callback($exception, $value);
         } catch (\Throwable $exception) {
             Loop::defer(static function () use($exception) {
                 throw $exception;
             });
         }
     }
 }
Пример #5
0
 /**
  * @param callable(callable(mixed $value): Promise $emit): \Generator $emitter
  *
  * @throws \Error Thrown if the callable does not return a Generator.
  */
 public function __construct(callable $emitter)
 {
     $result = $emitter($this->callableFromInstanceMethod("emit"));
     if (!$result instanceof \Generator) {
         throw new \Error("The callable did not return a Generator");
     }
     Loop::defer(function () use($result) {
         $coroutine = new Coroutine($result);
         $coroutine->when(function ($exception, $value) {
             if ($this->resolved) {
                 return;
             }
             if ($exception) {
                 $this->fail($exception);
                 return;
             }
             $this->resolve($value);
         });
     });
 }
Пример #6
0
 /**
  * Internal resolution
  *
  * @param $callback
  *
  * @throws \Exception|\Throwable
  */
 private function resolve($callback)
 {
     try {
         $callback();
     } catch (\Throwable $exception) {
         if ($this->hasActiveLoop()) {
             Loop::defer(static function () use($exception) {
                 throw $exception;
             });
         }
         throw $exception;
     } catch (\Exception $exception) {
         if ($this->hasActiveLoop()) {
             Loop::defer(static function () use($exception) {
                 throw $exception;
             });
         }
         throw $exception;
     }
 }
Пример #7
0
 protected function advance($val)
 {
     while (($this->valid = $this->generator->valid()) && $val instanceof Promise) {
         $done = false;
         $val->when(function (\Throwable $e = null, $v = null) use(&$val, &$done) {
             if (!$this->valid || !self::$alive) {
                 return;
             }
             if ($e) {
                 $this->dispose($e);
             } elseif ($done) {
                 $this->running = true;
                 try {
                     $this->advance($this->generator->send($v));
                     $this->running = false;
                     if ($this->error) {
                         $this->dispose($this->error);
                     }
                 } catch (\Throwable $e) {
                     $this->running = false;
                     $this->dispose($e);
                 }
             } else {
                 $done = true;
                 $val = $v;
             }
         });
         if (!$done || !self::$alive) {
             $done = true;
             $this->promise = $val;
             return;
         }
         $this->running = true;
         try {
             $val = $this->generator->send($val);
             $this->running = false;
             if ($this->error) {
                 return $this->dispose($this->error);
             }
         } catch (\Throwable $e) {
             $this->running = false;
             return $this->dispose($e);
         }
     }
     if ($this->valid) {
         return Loop::defer(function ($id, $val) {
             if (!$this->valid || !self::$alive) {
                 return;
             }
             $this->running = true;
             try {
                 $this->advance($this->generator->send($val));
                 $this->running = false;
                 if ($this->error) {
                     $this->dispose($this->error);
                 }
             } catch (\Throwable $e) {
                 $this->running = false;
                 $this->dispose($e);
             }
         }, $val);
     }
     if ($this->error) {
         return $this->dispose($this->error);
     }
     if ($this->state === self::PENDING) {
         $this->resolve($this->generator->getReturn());
     }
 }
Пример #8
0
 /**
  * Fail the awaitable with the given error.
  * 
  * @param \Throwable $error
  * 
  * @throws \RuntimeException If the awaitable has already been resolved or failed.
  */
 protected function fail(\Throwable $error)
 {
     if ($this->state !== Awaitable::PENDING) {
         return;
     }
     $this->state = Awaitable::FAILED;
     $this->result = $error;
     if ($this->callbacks) {
         try {
             foreach ($this->callbacks as $callback) {
                 try {
                     $callback($error);
                 } catch (\Throwable $ex) {
                     Loop::defer(function () use($ex) {
                         throw $ex;
                     });
                 }
             }
         } finally {
             $this->callbacks = null;
         }
     }
 }
Пример #9
0
 protected function dispose(\Throwable $e)
 {
     if ($this->promise) {
         $promise = $this->promise;
         $this->promise = null;
         Loop::defer(function () use($promise, $e) {
             $promise->cancel($e);
         });
     }
     $this->error = null;
     while ($this->valid = $this->generator->valid() && self::$alive) {
         $this->running = true;
         try {
             return $this->advance($this->generator->throw($e));
         } catch (\Throwable $e) {
             // Continue loop switching to the outer exception.
         } finally {
             $this->running = false;
         }
     }
     if (!self::$alive || !$this->valid && $this->state === Awaitable::PENDING) {
         $this->fail($e);
     }
 }