Skip to content

Commit 93d4b0f

Browse files
authored
Merge pull request #224 from clue-labs/no-done
[RFC] Remove `done()` method
2 parents 16052d3 + 5bf2110 commit 93d4b0f

14 files changed

+12
-634
lines changed

README.md

Lines changed: 0 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ Table of Contents
2929
* [Deferred::reject()](#deferredreject)
3030
* [PromiseInterface](#promiseinterface)
3131
* [PromiseInterface::then()](#promiseinterfacethen)
32-
* [PromiseInterface::done()](#promiseinterfacedone)
3332
* [PromiseInterface::catch()](#promiseinterfacecatch)
3433
* [PromiseInterface::finally()](#promiseinterfacefinally)
3534
* [PromiseInterface::cancel()](#promiseinterfacecancel)
@@ -48,7 +47,6 @@ Table of Contents
4847
* [Resolution forwarding](#resolution-forwarding)
4948
* [Rejection forwarding](#rejection-forwarding)
5049
* [Mixed resolution and rejection forwarding](#mixed-resolution-and-rejection-forwarding)
51-
* [done() vs. then()](#done-vs-then)
5250
5. [Install](#install)
5351
6. [Credits](#credits)
5452
7. [License](#license)
@@ -183,28 +181,6 @@ the same call to `then()`:
183181

184182
* [resolve()](#resolve) - Creating a resolved promise
185183
* [reject()](#reject) - Creating a rejected promise
186-
* [PromiseInterface::done()](#promiseinterfacedone)
187-
* [done() vs. then()](#done-vs-then)
188-
189-
#### PromiseInterface::done()
190-
191-
```php
192-
$promise->done(callable $onFulfilled = null, callable $onRejected = null);
193-
```
194-
195-
Consumes the promise's ultimate value if the promise fulfills, or handles the
196-
ultimate error.
197-
198-
It will cause a fatal error (`E_USER_ERROR`) if either `$onFulfilled` or
199-
`$onRejected` throw or return a rejected promise.
200-
201-
Since the purpose of `done()` is consumption rather than transformation,
202-
`done()` always returns `null`.
203-
204-
#### See also
205-
206-
* [PromiseInterface::then()](#promiseinterfacethen)
207-
* [done() vs. then()](#done-vs-then)
208184

209185
#### PromiseInterface::catch()
210186

@@ -579,74 +555,6 @@ $deferred->promise()
579555
$deferred->resolve(1); // Prints "Mixed 4"
580556
```
581557

582-
### done() vs. then()
583-
584-
The golden rule is:
585-
586-
Either return your promise, or call done() on it.
587-
588-
At a first glance, `then()` and `done()` seem very similar. However, there are
589-
important distinctions.
590-
591-
The intent of `then()` is to transform a promise's value and to pass or return
592-
a new promise for the transformed value along to other parts of your code.
593-
594-
The intent of `done()` is to consume a promise's value, transferring
595-
responsibility for the value to your code.
596-
597-
In addition to transforming a value, `then()` allows you to recover from, or
598-
propagate intermediate errors. Any errors that are not handled will be caught
599-
by the promise machinery and used to reject the promise returned by `then()`.
600-
601-
Calling `done()` transfers all responsibility for errors to your code. If an
602-
error (either a thrown exception or returned rejection) escapes the
603-
`$onFulfilled` or `$onRejected` callbacks you provide to `done()`, it will cause
604-
a fatal error.
605-
606-
```php
607-
function getJsonResult()
608-
{
609-
return queryApi()
610-
->then(
611-
// Transform API results to an object
612-
function ($jsonResultString) {
613-
return json_decode($jsonResultString);
614-
},
615-
// Transform API errors to an exception
616-
function ($jsonErrorString) {
617-
$object = json_decode($jsonErrorString);
618-
throw new ApiErrorException($object->errorMessage);
619-
}
620-
);
621-
}
622-
623-
// Here we provide no rejection handler. If the promise returned has been
624-
// rejected, the ApiErrorException will be thrown
625-
getJsonResult()
626-
->done(
627-
// Consume transformed object
628-
function ($jsonResultObject) {
629-
// Do something with $jsonResultObject
630-
}
631-
);
632-
633-
// Here we provide a rejection handler which will either throw while debugging
634-
// or log the exception
635-
getJsonResult()
636-
->done(
637-
function ($jsonResultObject) {
638-
// Do something with $jsonResultObject
639-
},
640-
function (ApiErrorException $exception) {
641-
if (isDebug()) {
642-
throw $exception;
643-
} else {
644-
logException($exception);
645-
}
646-
}
647-
);
648-
```
649-
650558
Install
651559
-------
652560

src/Internal/FulfilledPromise.php

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
use React\Promise\Promise;
66
use React\Promise\PromiseInterface;
77
use function React\Promise\enqueue;
8-
use function React\Promise\fatalError;
98
use function React\Promise\resolve;
109

1110
/**
@@ -41,25 +40,6 @@ public function then(callable $onFulfilled = null, callable $onRejected = null):
4140
});
4241
}
4342

44-
public function done(callable $onFulfilled = null, callable $onRejected = null): void
45-
{
46-
if (null === $onFulfilled) {
47-
return;
48-
}
49-
50-
enqueue(function () use ($onFulfilled) {
51-
try {
52-
$result = $onFulfilled($this->value);
53-
} catch (\Throwable $exception) {
54-
return fatalError($exception);
55-
}
56-
57-
if ($result instanceof PromiseInterface) {
58-
$result->done();
59-
}
60-
});
61-
}
62-
6343
public function catch(callable $onRejected): PromiseInterface
6444
{
6545
return $this;

src/Internal/RejectedPromise.php

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
use React\Promise\PromiseInterface;
77
use function React\Promise\_checkTypehint;
88
use function React\Promise\enqueue;
9-
use function React\Promise\fatalError;
109
use function React\Promise\resolve;
1110

1211
/**
@@ -38,29 +37,6 @@ public function then(callable $onFulfilled = null, callable $onRejected = null):
3837
});
3938
}
4039

41-
public function done(callable $onFulfilled = null, callable $onRejected = null): void
42-
{
43-
enqueue(function () use ($onRejected) {
44-
if (null === $onRejected) {
45-
return fatalError($this->reason);
46-
}
47-
48-
try {
49-
$result = $onRejected($this->reason);
50-
} catch (\Throwable $exception) {
51-
return fatalError($exception);
52-
}
53-
54-
if ($result instanceof self) {
55-
return fatalError($result->reason);
56-
}
57-
58-
if ($result instanceof PromiseInterface) {
59-
$result->done();
60-
}
61-
});
62-
}
63-
6440
public function catch(callable $onRejected): PromiseInterface
6541
{
6642
if (!_checkTypehint($onRejected, $this->reason)) {

src/Promise.php

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,19 +57,6 @@ static function () use (&$parent) {
5757
);
5858
}
5959

60-
public function done(callable $onFulfilled = null, callable $onRejected = null): void
61-
{
62-
if (null !== $this->result) {
63-
$this->result->done($onFulfilled, $onRejected);
64-
return;
65-
}
66-
67-
$this->handlers[] = static function (PromiseInterface $promise) use ($onFulfilled, $onRejected) {
68-
$promise
69-
->done($onFulfilled, $onRejected);
70-
};
71-
}
72-
7360
public function catch(callable $onRejected): PromiseInterface
7461
{
7562
return $this->then(null, static function ($reason) use ($onRejected) {
@@ -151,9 +138,15 @@ private function resolver(callable $onFulfilled = null, callable $onRejected = n
151138
{
152139
return function ($resolve, $reject) use ($onFulfilled, $onRejected) {
153140
$this->handlers[] = static function (PromiseInterface $promise) use ($onFulfilled, $onRejected, $resolve, $reject) {
154-
$promise
155-
->then($onFulfilled, $onRejected)
156-
->done($resolve, $reject);
141+
$promise = $promise->then($onFulfilled, $onRejected);
142+
143+
if ($promise instanceof self && $promise->result === null) {
144+
$promise->handlers[] = static function (PromiseInterface $promise) use ($resolve, $reject) {
145+
$promise->then($resolve, $reject);
146+
};
147+
} else {
148+
$promise->then($resolve, $reject);
149+
}
157150
};
158151
};
159152
}

src/PromiseInterface.php

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,6 @@ interface PromiseInterface
3434
*/
3535
public function then(?callable $onFulfilled = null, ?callable $onRejected = null): PromiseInterface;
3636

37-
/**
38-
* Consumes the promise's ultimate value if the promise fulfills, or handles the
39-
* ultimate error.
40-
*
41-
* It will cause a fatal error (`E_USER_ERROR`) if either `$onFulfilled` or
42-
* `$onRejected` throw or return a rejected promise.
43-
*
44-
* Since the purpose of `done()` is consumption rather than transformation,
45-
* `done()` always returns `null`.
46-
*
47-
* @param callable|null $onFulfilled
48-
* @param callable|null $onRejected
49-
* @return void
50-
*/
51-
public function done(callable $onFulfilled = null, callable $onRejected = null): void;
52-
5337
/**
5438
* Registers a rejection handler for promise. It is a shortcut for:
5539
*

src/functions.php

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ function all(array $promisesOrValues): PromiseInterface
8888
$values[$i] = null;
8989

9090
resolve($promiseOrValue)
91-
->done(
91+
->then(
9292
function ($mapped) use ($i, &$values, &$toResolve, $resolve): void {
9393
$values[$i] = $mapped;
9494

@@ -125,7 +125,7 @@ function race(array $promisesOrValues): PromiseInterface
125125
$cancellationQueue->enqueue($promiseOrValue);
126126

127127
resolve($promiseOrValue)
128-
->done($resolve, $reject);
128+
->then($resolve, $reject);
129129
}
130130
}, $cancellationQueue);
131131
}
@@ -187,7 +187,7 @@ function any(array $promisesOrValues): PromiseInterface
187187
$cancellationQueue->enqueue($promiseOrValue);
188188

189189
resolve($promiseOrValue)
190-
->done($fulfiller, $rejecter);
190+
->then($fulfiller, $rejecter);
191191
}
192192
}, $cancellationQueue);
193193
}
@@ -206,19 +206,6 @@ function enqueue(callable $task): void
206206
$queue->enqueue($task);
207207
}
208208

209-
/**
210-
* @internal
211-
*/
212-
function fatalError($error): void
213-
{
214-
try {
215-
\trigger_error($error, E_USER_ERROR);
216-
} catch (\Throwable $e) {
217-
\set_error_handler(null);
218-
\trigger_error($error, E_USER_ERROR);
219-
}
220-
}
221-
222209
/**
223210
* @internal
224211
*/

tests/ErrorCollector.php

Lines changed: 0 additions & 29 deletions
This file was deleted.

tests/PromiseTest.php

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -178,19 +178,6 @@ public function shouldRejectWithoutCreatingGarbageCyclesIfCancellerHoldsReferenc
178178
$this->assertSame(0, gc_collect_cycles());
179179
}
180180

181-
/** @test */
182-
public function shouldIgnoreNotifyAfterReject()
183-
{
184-
$promise = new Promise(function () { }, function ($resolve, $reject, $notify) {
185-
$reject(new \Exception('foo'));
186-
$notify(42);
187-
});
188-
189-
$promise->then(null, null, $this->expectCallableNever());
190-
$promise->cancel();
191-
}
192-
193-
194181
/** @test */
195182
public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingPromise()
196183
{
@@ -212,17 +199,6 @@ public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingPro
212199
$this->assertSame(0, gc_collect_cycles());
213200
}
214201

215-
/** @test */
216-
public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingPromiseWithDoneFollowers()
217-
{
218-
gc_collect_cycles();
219-
$promise = new Promise(function () { });
220-
$promise->done();
221-
unset($promise);
222-
223-
$this->assertSame(0, gc_collect_cycles());
224-
}
225-
226202
/** @test */
227203
public function shouldNotLeaveGarbageCyclesWhenRemovingLastReferenceToPendingPromiseWithCatchFollowers()
228204
{

0 commit comments

Comments
 (0)