-
-
Notifications
You must be signed in to change notification settings - Fork 146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cancellable promise #20
Conversation
Because a Deferred value is the thing that is waiting to be resolved or rejected, I would imagine that a deferred value would also be the thing that is cancelled, not a promise (from what I can tell, that's what when.js is doing too, though it's marked as deprecated). What is the reasoning for adding this to the library vs just having the users of this library implement a method for cancelling deferred values? |
I'm not sure i understand the question, can you elaborate? A Deferred represents a computation. The promise represents the result of that computation, it is the value of a Deferred. Calling cancel() on a Promise signals the producer of the promise (which controls the Deferred) that there is no longer interest in this value. The producer may implement a mechanism to cancel the computation. function readLargeRemoteFile()
{
$canceller = function($resolve, $reject) use (&$request) {
$request->abort();
$reject(new RequestAbortedException());
};
$deferred = new Deferred($canceller);
$request = (new Client())->request();
$request->then([$deferred, 'resolve'], [$deferred, 'reject']);
return $deferred->promise();
}
$promise = readLargeRemoteFile();
$promise->cancel(); |
return new static($this->resolver($onFulfilled, $onRejected, $onProgress)); | ||
$this->requiredCancelRequests++; | ||
|
||
return new static($this->resolver($onFulfilled, $onRejected, $onProgress), function ($resolve, $reject, $progress) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you consider adding a check to conditionally return this new behavior vs the old behavior based on if a canceller is associated with the promise? Creating a new closure when it isn't necessary would add overhead where it isn't going to be utilized.
Something like:
if (!$this->canceller) {
return new static($this->resolver($onFulfilled, $onRejected, $onProgress));
}
// Return the new stuff you're adding here...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, done in 77f78d9
My point was that up until now, a promise was delivered a value from a deferred, and there was no way to send a message from the promise to the deferred (e.g., cancelling a computation). Are other promise implementations doing anything similar? |
Yes, that was also my concern. Many implementations immediately cancel the promise which gives promise consumers resolver capabilities. Because of that, i decided to handle cancellelations like notifications for the producer which can then decide to cancel, reject or just do nothing. Popular promise libraries which implement cancellable promises are Bluebird, WinJS, Dojo |
+1 from @cboden, @clue and @WyriHaximus via IRC. @cboden Ready to merge. |
Will review this weekend. |
Oh, yes. Sorry for the confusion 😊 |
@@ -1,6 +1,11 @@ | |||
CHANGELOG | |||
========= | |||
|
|||
* 2.1.x (xxxx-xx-xx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just remember to update this before tagging. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep 😎
Added CancellablePromiseInterface implemented by all promises.
Note on the implementation:
The
$canceller
callback is responsible for rejecting the promise, there is no automatic rejection mechanism (See https://github.com/reactphp/promise/tree/cancellable-promise#promise-1).The
$canceller
callback is invoked only, ifcancel()
is called either on the root promise or on all derived promises.Called on root promise
Called on derived promises