diff --git a/src/Utils/Coroutine/Handlers/RippleCoroutine.php b/src/Utils/Coroutine/Handlers/RippleCoroutine.php index c15c8eb..a835682 100644 --- a/src/Utils/Coroutine/Handlers/RippleCoroutine.php +++ b/src/Utils/Coroutine/Handlers/RippleCoroutine.php @@ -7,57 +7,66 @@ namespace Workbunny\WebmanCoroutine\Utils\Coroutine\Handlers; -use function Co\async; - +use Closure; use Psc\Core\Coroutine\Promise; +use Revolt\EventLoop\Suspension; class RippleCoroutine implements CoroutineInterface { /** - * @var null|Promise + * @var \Revolt\EventLoop\Suspension */ - protected ?Promise $_promise = null; + protected Suspension $suspension; /** @inheritdoc * @param \Closure $func */ - public function __construct(\Closure $func) + public function __construct(Closure $func) { - $this->_promise = $promise = $this->_async(function () use (&$promise, $func) { + $this->_async(function (Closure $resolve, Closure $reject) use ($func) { + $this->suspension = \Co\getSuspension(); + try { - call_user_func($func, spl_object_hash($this->_promise)); + $result = call_user_func( + $func, + spl_object_hash($this->origin()) + ); + + $resolve($result); + } catch (\Throwable $exception) { + $reject($exception); } finally { - // 移除协程promise - $this->_promise = null; + unset($this->promise); } }); } - /** @inheritdoc */ + /** @inheritdoc */ public function __destruct() { - $this->_promise = null; } - /** @inheritdoc */ - public function origin(): ?Promise + /** @inheritdoc */ + public function origin(): Suspension { - return $this->_promise; + return $this->suspension; } - /** @inheritdoc */ + /** @inheritdoc */ public function id(): ?string { - return $this->_promise ? spl_object_hash($this->_promise) : null; + return spl_object_hash($this->origin()); } /** * @codeCoverageIgnore 用于测试mock,忽略覆盖 + * * @param \Closure $closure - * @return mixed + * + * @return \Psc\Core\Coroutine\Promise */ - protected function _async(\Closure $closure) + protected function _async(Closure $closure): Promise { - return async($closure); + return \Co\async($closure); } } diff --git a/tests/UtilsCase/Coroutine/RippleCoroutineTest.php b/tests/UtilsCase/Coroutine/RippleCoroutineTest.php index 2891ee2..f4c2777 100644 --- a/tests/UtilsCase/Coroutine/RippleCoroutineTest.php +++ b/tests/UtilsCase/Coroutine/RippleCoroutineTest.php @@ -27,7 +27,7 @@ public function testConstruct() // mock async $callback = null; - $promiseMock = Mockery::mock('Psc\Core\Coroutine\Promise'); + $promiseMock = Mockery::mock('Revolt\EventLoop\Suspension'); $coroutine = Mockery::mock(RippleCoroutine::class)->makePartial(); $coroutine->shouldAllowMockingProtectedMethods()->shouldReceive('_async') ->andReturnUsing(function ($closure) use (&$callback, $promiseMock) { @@ -40,7 +40,7 @@ public function testConstruct() $constructor->invoke($coroutine, $func); $this->assertFalse($executed); - $this->assertInstanceOf('Psc\Core\Coroutine\Promise', $coroutine->origin()); + $this->assertInstanceOf('Revolt\EventLoop\Suspension', $coroutine->origin()); $this->assertIsString($getId = $coroutine->id()); $this->assertEquals(spl_object_hash($promiseMock), $coroutine->id()); $this->assertNull($id); @@ -63,7 +63,7 @@ public function testDestruct() // mock async $callback = null; - $promiseMock = Mockery::mock('Psc\Core\Coroutine\Promise'); + $promiseMock = Mockery::mock('Revolt\EventLoop\Suspension'); $coroutine = Mockery::mock(RippleCoroutine::class)->makePartial(); $coroutine->shouldAllowMockingProtectedMethods()->shouldReceive('_async') ->andReturnUsing(function ($closure) use (&$callback, $promiseMock) { @@ -91,7 +91,7 @@ public function testOrigin() }; // mock async $callback = null; - $promiseMock = Mockery::mock('Psc\Core\Coroutine\Promise'); + $promiseMock = Mockery::mock('Revolt\EventLoop\Suspension'); $coroutine = Mockery::mock(RippleCoroutine::class)->makePartial(); $coroutine->shouldAllowMockingProtectedMethods()->shouldReceive('_async') ->andReturnUsing(function ($closure) use (&$callback, $promiseMock) { @@ -103,7 +103,7 @@ public function testOrigin() $constructor = new \ReflectionMethod(RippleCoroutine::class, '__construct'); $constructor->invoke($coroutine, $func); - $this->assertInstanceOf('Psc\Core\Coroutine\Promise', $coroutine->origin()); + $this->assertInstanceOf('Revolt\EventLoop\Suspension', $coroutine->origin()); // 模拟构造后协程执行callback call_user_func($callback); @@ -117,7 +117,7 @@ public function testId() }; // mock async $callback = null; - $promiseMock = Mockery::mock('Psc\Core\Coroutine\Promise'); + $promiseMock = Mockery::mock('Revolt\EventLoop\Suspension'); $coroutine = Mockery::mock(RippleCoroutine::class)->makePartial(); $coroutine->shouldAllowMockingProtectedMethods()->shouldReceive('_async') ->andReturnUsing(function ($closure) use (&$callback, $promiseMock) {