diff --git a/README.md b/README.md index 6cd4dbf5..a87b1363 100644 --- a/README.md +++ b/README.md @@ -29,8 +29,10 @@ Table of Contents * [PromiseInterface](#promiseinterface) * [PromiseInterface::then()](#promiseinterfacethen) * [PromiseInterface::done()](#promiseinterfacedone) - * [PromiseInterface::otherwise()](#promiseinterfaceotherwise) - * [PromiseInterface::always()](#promiseinterfacealways) + * [~~PromiseInterface::otherwise()~~](#promiseinterfaceotherwise) + * [PromiseInterface::catch()](#promiseinterfacecatch) + * [~~PromiseInterface::always()~~](#promiseinterfacealways) + * [PromiseInterface::finally()](#promiseinterfacefinally) * [PromiseInterface::cancel()](#promiseinterfacecancel) * [Promise](#promise-2) * [Functions](#functions) @@ -206,10 +208,14 @@ Since the purpose of `done()` is consumption rather than transformation, * [PromiseInterface::then()](#promiseinterfacethen) * [done() vs. then()](#done-vs-then) -#### PromiseInterface::otherwise() +#### ~~PromiseInterface::otherwise()~~ + +The `otherwise` method has been deprecated in favour of [`catch`](#promiseinterfacecatch) + +#### PromiseInterface::catch() ```php -$promise->otherwise(callable $onRejected); +$promise->catch(callable $onRejected); ``` Registers a rejection handler for promise. It is a shortcut for: @@ -223,19 +229,23 @@ only specific errors. ```php $promise - ->otherwise(function (\RuntimeException $reason) { + ->catch(function (\RuntimeException $reason) { // Only catch \RuntimeException instances // All other types of errors will propagate automatically }) - ->otherwise(function (\Throwable $reason) { + ->catch(function (\Throwable $reason) { // Catch other errors }); ``` -#### PromiseInterface::always() +#### ~~PromiseInterface::always()~~ + +The `otherwise` method has been deprecated in favour of [`finally`](#promiseinterfacefinally) + +#### PromiseInterface::finally() ```php -$newPromise = $promise->always(callable $onFulfilledOrRejected); +$newPromise = $promise->finally(callable $onFulfilledOrRejected); ``` Allows you to execute "cleanup" type tasks in a promise chain. @@ -254,8 +264,8 @@ when the promise is either fulfilled or rejected. rejected promise, `$newPromise` will reject with the thrown exception or rejected promise's reason. -`always()` behaves similarly to the synchronous finally statement. When combined -with `otherwise()`, `always()` allows you to write code that is similar to the familiar +`finally()` behaves similarly to the synchronous finally statement. When combined +with `catch()`, `finally()` allows you to write code that is similar to the familiar synchronous catch/finally pair. Consider the following synchronous code: @@ -275,8 +285,8 @@ written: ```php return doSomething() - ->otherwise('handleError') - ->always('cleanup'); + ->catch('handleError') + ->finally('cleanup'); ``` #### PromiseInterface::cancel() @@ -559,17 +569,17 @@ $deferred->promise() ->then(function ($x) { throw new \Exception($x + 1); }) - ->otherwise(function (\Exception $x) { + ->catch(function (\Exception $x) { // Propagate the rejection throw $x; }) - ->otherwise(function (\Exception $x) { + ->catch(function (\Exception $x) { // Can also propagate by returning another rejection return React\Promise\reject( new \Exception($x->getMessage() + 1) ); }) - ->otherwise(function ($x) { + ->catch(function ($x) { echo 'Reject ' . $x->getMessage(); // 3 }); @@ -591,7 +601,7 @@ $deferred->promise() ->then(function ($x) { throw new \Exception($x + 1); }) - ->otherwise(function (\Exception $x) { + ->catch(function (\Exception $x) { // Handle the rejection, and don't propagate. // This is like catch without a rethrow return $x->getMessage() + 1; diff --git a/src/Internal/FulfilledPromise.php b/src/Internal/FulfilledPromise.php index e95d5aa4..c0584371 100644 --- a/src/Internal/FulfilledPromise.php +++ b/src/Internal/FulfilledPromise.php @@ -60,12 +60,28 @@ public function done(callable $onFulfilled = null, callable $onRejected = null): }); } + /** + * @deprecated Use catch instead + */ public function otherwise(callable $onRejected): PromiseInterface + { + return $this->catch($onRejected); + } + + public function catch(callable $onRejected): PromiseInterface { return $this; } + /** + * @deprecated Use finally instead + */ public function always(callable $onFulfilledOrRejected): PromiseInterface + { + return $this->finally($onFulfilledOrRejected); + } + + public function finally(callable $onFulfilledOrRejected): PromiseInterface { return $this->then(function ($value) use ($onFulfilledOrRejected): PromiseInterface { return resolve($onFulfilledOrRejected())->then(function () use ($value) { diff --git a/src/Internal/RejectedPromise.php b/src/Internal/RejectedPromise.php index da50cde4..e515e2e2 100644 --- a/src/Internal/RejectedPromise.php +++ b/src/Internal/RejectedPromise.php @@ -61,7 +61,15 @@ public function done(callable $onFulfilled = null, callable $onRejected = null): }); } + /** + * @deprecated Use catch instead + */ public function otherwise(callable $onRejected): PromiseInterface + { + return $this->catch($onRejected); + } + + public function catch(callable $onRejected): PromiseInterface { if (!_checkTypehint($onRejected, $this->reason)) { return $this; @@ -70,7 +78,15 @@ public function otherwise(callable $onRejected): PromiseInterface return $this->then(null, $onRejected); } + /** + * @deprecated Use finally instead + */ public function always(callable $onFulfilledOrRejected): PromiseInterface + { + return $this->finally($onFulfilledOrRejected); + } + + public function finally(callable $onFulfilledOrRejected): PromiseInterface { return $this->then(null, function (\Throwable $reason) use ($onFulfilledOrRejected): PromiseInterface { return resolve($onFulfilledOrRejected())->then(function () use ($reason): PromiseInterface { diff --git a/src/Promise.php b/src/Promise.php index a4765e08..3ce03c95 100644 --- a/src/Promise.php +++ b/src/Promise.php @@ -70,7 +70,15 @@ public function done(callable $onFulfilled = null, callable $onRejected = null): }; } + /** + * @deprecated Use catch instead + */ public function otherwise(callable $onRejected): PromiseInterface + { + return $this->catch($onRejected); + } + + public function catch(callable $onRejected): PromiseInterface { return $this->then(null, static function ($reason) use ($onRejected) { if (!_checkTypehint($onRejected, $reason)) { @@ -81,7 +89,15 @@ public function otherwise(callable $onRejected): PromiseInterface }); } + /** + * @deprecated Use finally instead + */ public function always(callable $onFulfilledOrRejected): PromiseInterface + { + return $this->finally($onFulfilledOrRejected); + } + + public function finally(callable $onFulfilledOrRejected): PromiseInterface { return $this->then(static function ($value) use ($onFulfilledOrRejected) { return resolve($onFulfilledOrRejected())->then(function () use ($value) { diff --git a/src/PromiseInterface.php b/src/PromiseInterface.php index 3f854b94..4838f03a 100644 --- a/src/PromiseInterface.php +++ b/src/PromiseInterface.php @@ -50,6 +50,14 @@ public function then(?callable $onFulfilled = null, ?callable $onRejected = null */ public function done(callable $onFulfilled = null, callable $onRejected = null): void; + /** + * @see catch + * @deprecated Use catch instead + * @param callable $onRejected + * @return PromiseInterface + */ + public function otherwise(callable $onRejected): PromiseInterface; + /** * Registers a rejection handler for promise. It is a shortcut for: * @@ -63,7 +71,7 @@ public function done(callable $onFulfilled = null, callable $onRejected = null): * @param callable $onRejected * @return PromiseInterface */ - public function otherwise(callable $onRejected): PromiseInterface; + public function catch(callable $onRejected): PromiseInterface; /** * Allows you to execute "cleanup" type tasks in a promise chain. diff --git a/tests/PromiseTest.php b/tests/PromiseTest.php index 6af65ce5..e39df702 100644 --- a/tests/PromiseTest.php +++ b/tests/PromiseTest.php @@ -228,7 +228,7 @@ public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingPro { gc_collect_cycles(); $promise = new Promise(function () { }); - $promise->otherwise(function () { }); + $promise->catch(function () { }); unset($promise); $this->assertSame(0, gc_collect_cycles()); @@ -239,7 +239,7 @@ public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingPro { gc_collect_cycles(); $promise = new Promise(function () { }); - $promise->always(function () { }); + $promise->finally(function () { }); unset($promise); $this->assertSame(0, gc_collect_cycles()); diff --git a/tests/PromiseTest/PromiseFulfilledTestTrait.php b/tests/PromiseTest/PromiseFulfilledTestTrait.php index 0b79a95b..16c67157 100644 --- a/tests/PromiseTest/PromiseFulfilledTestTrait.php +++ b/tests/PromiseTest/PromiseFulfilledTestTrait.php @@ -266,7 +266,7 @@ public function otherwiseShouldNotInvokeRejectionHandlerForFulfilledPromise() $adapter = $this->getPromiseTestAdapter(); $adapter->resolve(1); - $adapter->promise()->otherwise($this->expectCallableNever()); + $adapter->promise()->catch($this->expectCallableNever()); } /** @test */ @@ -284,7 +284,7 @@ public function alwaysShouldNotSuppressValueForFulfilledPromise() $adapter->resolve($value); $adapter->promise() - ->always(function () {}) + ->finally(function () {}) ->then($mock); } @@ -303,7 +303,7 @@ public function alwaysShouldNotSuppressValueWhenHandlerReturnsANonPromiseForFulf $adapter->resolve($value); $adapter->promise() - ->always(function () { + ->finally(function () { return 1; }) ->then($mock); @@ -324,7 +324,7 @@ public function alwaysShouldNotSuppressValueWhenHandlerReturnsAPromiseForFulfill $adapter->resolve($value); $adapter->promise() - ->always(function () { + ->finally(function () { return resolve(1); }) ->then($mock); @@ -345,7 +345,7 @@ public function alwaysShouldRejectWhenHandlerThrowsForFulfilledPromise() $adapter->resolve(1); $adapter->promise() - ->always(function () use ($exception) { + ->finally(function () use ($exception) { throw $exception; }) ->then(null, $mock); @@ -366,7 +366,7 @@ public function alwaysShouldRejectWhenHandlerRejectsForFulfilledPromise() $adapter->resolve(1); $adapter->promise() - ->always(function () use ($exception) { + ->finally(function () use ($exception) { return reject($exception); }) ->then(null, $mock); diff --git a/tests/PromiseTest/PromisePendingTestTrait.php b/tests/PromiseTest/PromisePendingTestTrait.php index 87d18c32..b72c9d17 100644 --- a/tests/PromiseTest/PromisePendingTestTrait.php +++ b/tests/PromiseTest/PromisePendingTestTrait.php @@ -58,7 +58,7 @@ public function otherwiseShouldNotInvokeRejectionHandlerForPendingPromise() $adapter = $this->getPromiseTestAdapter(); $adapter->settle(); - $adapter->promise()->otherwise($this->expectCallableNever()); + $adapter->promise()->catch($this->expectCallableNever()); } /** @test */ @@ -66,6 +66,6 @@ public function alwaysShouldReturnAPromiseForPendingPromise() { $adapter = $this->getPromiseTestAdapter(); - self::assertInstanceOf(PromiseInterface::class, $adapter->promise()->always(function () {})); + self::assertInstanceOf(PromiseInterface::class, $adapter->promise()->finally(function () {})); } } diff --git a/tests/PromiseTest/PromiseRejectedTestTrait.php b/tests/PromiseTest/PromiseRejectedTestTrait.php index 68b401c4..13fdf589 100644 --- a/tests/PromiseTest/PromiseRejectedTestTrait.php +++ b/tests/PromiseTest/PromiseRejectedTestTrait.php @@ -325,7 +325,7 @@ public function otherwiseShouldInvokeRejectionHandlerForRejectedPromise() ->with($this->identicalTo($exception)); $adapter->reject($exception); - $adapter->promise()->otherwise($mock); + $adapter->promise()->catch($mock); } /** @test */ @@ -343,7 +343,7 @@ public function otherwiseShouldInvokeNonTypeHintedRejectionHandlerIfReasonIsAnEx $adapter->reject($exception); $adapter->promise() - ->otherwise(function ($reason) use ($mock) { + ->catch(function ($reason) use ($mock) { $mock($reason); }); } @@ -363,7 +363,7 @@ public function otherwiseShouldInvokeRejectionHandlerIfReasonMatchesTypehintForR $adapter->reject($exception); $adapter->promise() - ->otherwise(function (InvalidArgumentException $reason) use ($mock) { + ->catch(function (InvalidArgumentException $reason) use ($mock) { $mock($reason); }); } @@ -379,7 +379,7 @@ public function otherwiseShouldNotInvokeRejectionHandlerIfReaonsDoesNotMatchType $adapter->reject($exception); $adapter->promise() - ->otherwise(function (InvalidArgumentException $reason) use ($mock) { + ->catch(function (InvalidArgumentException $reason) use ($mock) { $mock($reason); }); } @@ -399,7 +399,7 @@ public function alwaysShouldNotSuppressRejectionForRejectedPromise() $adapter->reject($exception); $adapter->promise() - ->always(function () {}) + ->finally(function () {}) ->then(null, $mock); } @@ -418,7 +418,7 @@ public function alwaysShouldNotSuppressRejectionWhenHandlerReturnsANonPromiseFor $adapter->reject($exception); $adapter->promise() - ->always(function () { + ->finally(function () { return 1; }) ->then(null, $mock); @@ -439,7 +439,7 @@ public function alwaysShouldNotSuppressRejectionWhenHandlerReturnsAPromiseForRej $adapter->reject($exception); $adapter->promise() - ->always(function () { + ->finally(function () { return resolve(1); }) ->then(null, $mock); @@ -461,7 +461,7 @@ public function alwaysShouldRejectWhenHandlerThrowsForRejectedPromise() $adapter->reject($exception1); $adapter->promise() - ->always(function () use ($exception2) { + ->finally(function () use ($exception2) { throw $exception2; }) ->then(null, $mock); @@ -483,7 +483,7 @@ public function alwaysShouldRejectWhenHandlerRejectsForRejectedPromise() $adapter->reject($exception1); $adapter->promise() - ->always(function () use ($exception2) { + ->finally(function () use ($exception2) { return reject($exception2); }) ->then(null, $mock); diff --git a/tests/PromiseTest/PromiseSettledTestTrait.php b/tests/PromiseTest/PromiseSettledTestTrait.php index 626011e1..2546ebdc 100644 --- a/tests/PromiseTest/PromiseSettledTestTrait.php +++ b/tests/PromiseTest/PromiseSettledTestTrait.php @@ -74,6 +74,6 @@ public function alwaysShouldReturnAPromiseForSettledPromise() $adapter = $this->getPromiseTestAdapter(); $adapter->settle(); - self::assertInstanceOf(PromiseInterface::class, $adapter->promise()->always(function () {})); + self::assertInstanceOf(PromiseInterface::class, $adapter->promise()->finally(function () {})); } } diff --git a/tests/PromiseTest/RejectTestTrait.php b/tests/PromiseTest/RejectTestTrait.php index c089e0ad..931137e3 100644 --- a/tests/PromiseTest/RejectTestTrait.php +++ b/tests/PromiseTest/RejectTestTrait.php @@ -104,7 +104,7 @@ public function rejectShouldInvokeOtherwiseHandler() ->with($this->identicalTo($exception)); $adapter->promise() - ->otherwise($mock); + ->catch($mock); $adapter->reject($exception); } @@ -260,7 +260,7 @@ public function alwaysShouldNotSuppressRejection() ->with($this->identicalTo($exception)); $adapter->promise() - ->always(function () {}) + ->finally(function () {}) ->then(null, $mock); $adapter->reject($exception); @@ -280,7 +280,7 @@ public function alwaysShouldNotSuppressRejectionWhenHandlerReturnsANonPromise() ->with($this->identicalTo($exception)); $adapter->promise() - ->always(function () { + ->finally(function () { return 1; }) ->then(null, $mock); @@ -302,7 +302,7 @@ public function alwaysShouldNotSuppressRejectionWhenHandlerReturnsAPromise() ->with($this->identicalTo($exception)); $adapter->promise() - ->always(function () { + ->finally(function () { return resolve(1); }) ->then(null, $mock); @@ -324,7 +324,7 @@ public function alwaysShouldRejectWhenHandlerThrowsForRejection() ->with($this->identicalTo($exception)); $adapter->promise() - ->always(function () use ($exception) { + ->finally(function () use ($exception) { throw $exception; }) ->then(null, $mock); @@ -346,7 +346,7 @@ public function alwaysShouldRejectWhenHandlerRejectsForRejection() ->with($this->identicalTo($exception)); $adapter->promise() - ->always(function () use ($exception) { + ->finally(function () use ($exception) { return reject($exception); }) ->then(null, $mock); diff --git a/tests/PromiseTest/ResolveTestTrait.php b/tests/PromiseTest/ResolveTestTrait.php index 23105bfd..8f67fec6 100644 --- a/tests/PromiseTest/ResolveTestTrait.php +++ b/tests/PromiseTest/ResolveTestTrait.php @@ -236,7 +236,7 @@ public function alwaysShouldNotSuppressValue() ->with($this->identicalTo($value)); $adapter->promise() - ->always(function () {}) + ->finally(function () {}) ->then($mock); $adapter->resolve($value); @@ -256,7 +256,7 @@ public function alwaysShouldNotSuppressValueWhenHandlerReturnsANonPromise() ->with($this->identicalTo($value)); $adapter->promise() - ->always(function () { + ->finally(function () { return 1; }) ->then($mock); @@ -278,7 +278,7 @@ public function alwaysShouldNotSuppressValueWhenHandlerReturnsAPromise() ->with($this->identicalTo($value)); $adapter->promise() - ->always(function () { + ->finally(function () { return resolve(1); }) ->then($mock); @@ -300,7 +300,7 @@ public function alwaysShouldRejectWhenHandlerThrowsForFulfillment() ->with($this->identicalTo($exception)); $adapter->promise() - ->always(function () use ($exception) { + ->finally(function () use ($exception) { throw $exception; }) ->then(null, $mock); @@ -322,7 +322,7 @@ public function alwaysShouldRejectWhenHandlerRejectsForFulfillment() ->with($this->identicalTo($exception)); $adapter->promise() - ->always(function () use ($exception) { + ->finally(function () use ($exception) { return reject($exception); }) ->then(null, $mock);