From 3d93a305d6e2aeb20c7915954d4dd44dcb4c422d Mon Sep 17 00:00:00 2001 From: Jeremiah VALERIE Date: Mon, 14 Nov 2016 17:29:15 +0100 Subject: [PATCH] Add some optimizations * add cancel * No argument required for resolve * Fix guzzle all when argument empty --- composer.json | 1 + src/Factory/GuzzleHttpPromiseFactory.php | 21 ++++++++++++--- src/Factory/ReactPromiseFactory.php | 16 +++++++++++- src/PromiseFactoryInterface.php | 10 +++++-- tests/FactoryTest.php | 33 ++++++++++++++++++++++++ 5 files changed, 75 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index 6663072..0415521 100644 --- a/composer.json +++ b/composer.json @@ -2,6 +2,7 @@ "name": "mcg-web/promise-factory", "description": "This library tries to create a simple promise factory standard while waiting for a psr.", "type": "library", + "keywords": ["promise", "factory", "guzzle", "react"], "autoload": { "psr-4": { "McGWeb\\PromiseFactory\\": "src/" diff --git a/src/Factory/GuzzleHttpPromiseFactory.php b/src/Factory/GuzzleHttpPromiseFactory.php index 278f554..4c62cde 100644 --- a/src/Factory/GuzzleHttpPromiseFactory.php +++ b/src/Factory/GuzzleHttpPromiseFactory.php @@ -26,7 +26,8 @@ class GuzzleHttpPromiseFactory implements PromiseFactoryInterface */ public static function create(&$resolve = null, &$reject = null, callable $canceller = null) { - $promise = new Promise(null, $canceller); + $queue = \GuzzleHttp\Promise\queue(); + $promise = new Promise([$queue, 'run'], $canceller); $reject = [$promise, 'reject']; $resolve = [$promise, 'resolve']; @@ -39,7 +40,7 @@ public static function create(&$resolve = null, &$reject = null, callable $cance * * @return FulfilledPromise a full filed Promise */ - public static function createResolve($promiseOrValue) + public static function createResolve($promiseOrValue = null) { $promise = \GuzzleHttp\Promise\promise_for($promiseOrValue); @@ -65,7 +66,7 @@ public static function createReject($promiseOrValue) */ public static function createAll($promisesOrValues) { - $promise = \GuzzleHttp\Promise\all($promisesOrValues); + $promise = empty($promisesOrValues) ? static::createResolve($promisesOrValues) : \GuzzleHttp\Promise\all($promisesOrValues); return $promise; } @@ -96,6 +97,7 @@ public static function await($promise = null, $unwrap = false) if (!static::isPromise($promise)) { throw new \InvalidArgumentException(sprintf('The "%s" method must be called with a Promise ("then" method).', __METHOD__)); } + /** @var Promise $promise */ $promise->then(function ($values) use (&$resolvedValue) { $resolvedValue = $values; @@ -116,4 +118,17 @@ public static function await($promise = null, $unwrap = false) return $resolvedValue; } + + /** + * Cancel a promise + * + * @param PromiseInterface $promise + */ + public static function cancel($promise) + { + if (!static::isPromise($promise, true)) { + throw new \InvalidArgumentException(sprintf('The "%s" method must be called with a compatible Promise.', __METHOD__)); + } + $promise->cancel(); + } } diff --git a/src/Factory/ReactPromiseFactory.php b/src/Factory/ReactPromiseFactory.php index da19ebb..40daea8 100644 --- a/src/Factory/ReactPromiseFactory.php +++ b/src/Factory/ReactPromiseFactory.php @@ -12,6 +12,7 @@ namespace McGWeb\PromiseFactory\Factory; use McGWeb\PromiseFactory\PromiseFactoryInterface; +use React\Promise\CancellablePromiseInterface; use React\Promise\Deferred; use React\Promise\FulfilledPromise; use React\Promise\Promise; @@ -40,7 +41,7 @@ public static function create(&$resolve = null, &$reject = null, callable $cance * * @return FulfilledPromise a full filed Promise */ - public static function createResolve($promiseOrValue) + public static function createResolve($promiseOrValue = null) { return \React\Promise\resolve($promiseOrValue); } @@ -107,4 +108,17 @@ public static function await($promise = null, $unwrap = false) return $resolvedValue; } + + /** + * Cancel a promise + * + * @param CancellablePromiseInterface $promise + */ + public static function cancel($promise) + { + if (!$promise instanceof CancellablePromiseInterface) { + throw new \InvalidArgumentException(sprintf('The "%s" method must be called with a compatible Promise.', __METHOD__)); + } + $promise->cancel(); + } } diff --git a/src/PromiseFactoryInterface.php b/src/PromiseFactoryInterface.php index f864505..4d77b67 100644 --- a/src/PromiseFactoryInterface.php +++ b/src/PromiseFactoryInterface.php @@ -31,7 +31,7 @@ public static function create(&$resolve = null, &$reject = null, callable $cance * * @return mixed a full filed Promise */ - public static function createResolve($promiseOrValue); + public static function createResolve($promiseOrValue = null); /** * Creates a rejected promise for a reason if the reason is not a promise. If @@ -53,7 +53,6 @@ public static function createReject($promiseOrValue); */ public static function createAll($promisesOrValues); - /** * Check if value is a promise * @@ -72,4 +71,11 @@ public static function isPromise($value, $strict = false); * @return mixed */ public static function await($promise = null, $unwrap = false); + + /** + * Cancel a promise + * + * @param $promise + */ + public static function cancel($promise); } diff --git a/tests/FactoryTest.php b/tests/FactoryTest.php index a47b39e..fe38f1b 100644 --- a/tests/FactoryTest.php +++ b/tests/FactoryTest.php @@ -173,6 +173,39 @@ public function testAwaitWithInvalidPromise(PromiseFactoryInterface $factory) $factory->await(new \stdClass(), true); } + /** + * @dataProvider factoryDataProvider + * @param PromiseFactoryInterface $factory + * + * @expectedException \Exception + * @expectedExceptionMessage Cancel promise! + */ + public function testCancel(PromiseFactoryInterface $factory) + { + $promise = $factory->create($resolve, $reject, function () { + throw new \Exception('Cancel promise!'); + }); + + $factory->cancel($promise); + $factory->await($promise, true); + } + + /** + * @dataProvider factoryDataProvider + * @param PromiseFactoryInterface $factory + * + * @expectedException \Exception + * @expectedExceptionMessage ::cancel" method must be called with a compatible Promise. + */ + public function testCancelInvalidPromise(PromiseFactoryInterface $factory) + { + $factory->create($resolve, $reject, function () { + throw new \Exception('Cancel will never be called!'); + }); + + $factory->cancel(new \stdClass()); + } + public function factoryDataProvider() { return [