Promise-returning delay function

C. Scott Ananian ecmascript at cscott.net
Tue Oct 28 08:34:10 PDT 2014


Dean, your idea is even better as a `Promise` *subclass*.

The subclassed cancellable promises could share a cancel flag, and
throw an exception (or resolve to a different value, whichever you
like better for the API) when the cancel flag is set.  The `then`
method on `CancellablePromise` returns another `CancellablePromise`
(the spec is nicely written this way), and you use `Promise.resolve`
to cast to a standard `Promise` to end the cancellation chain at an
appropriate place.

See the `Promise.bind` implementation in `prfun` for an example of
using subclasses in this way:
https://github.com/cscott/prfun/blob/master/lib/index.js#L518
  --scott

ps. Of course, to be precise, your API would be a factory function
which makes a new subclass of `CancellablePromise` for each cancel
scope, since the Promise spec associates the state with the
constructor identity.  (I had some small issues with the "new subclass
for each X" mechanism in an earlier attempt at creating MonadicPromise
using subclasses, but I think these were ultimately resolved in the
spec---and in that case I was creating a new subclass for each call to
`Promise.resolve`, which was a whole 'nuther kettle of fish.)


On Tue, Oct 28, 2014 at 11:21 AM, Dean Landolt <dean at deanlandolt.com> wrote:
> On Tue, Oct 28, 2014 at 10:41 AM, Andrea Giammarchi
> <andrea.giammarchi at gmail.com> wrote:
>>
>> The moment you pass a promise you have no control on who's adding what as
>> callback or errorback which means you have no control over a .reject() or
>> over a .success()
>>
>> .cancel() would eventually keep both queues unresolved so that nothing
>> should happen at all: no error handling, no error happened, and no actions
>> needed ... it's simply canceled.
>>
>> This is the same reason .fetch() API needs also events to work properly
>> (including `progress`) ... you "cannot" base as example typeahead on
>> promises right now 'cause it's a mess to handle since response order is not
>> guaranteed but you need to handle the .cancel() case without telling the
>> user something else went wrong ... what you suggest, a `new Noop()` where
>> `Noop.prototype = Object.create(Error.prototype)` ?
>>
>> And how do you instruct unknown surrounding code that an `if (err
>> instanceof Noop)` should be the first line of every errback ?
>>
>> This is the reason few devs cannot adopt current standard Promises.
>>
>> `.cancel()` as well as `.abort()` is **very** important when many network
>> operations are in place and/or you want to switch to a different state
>> without waiting for the previous one to be fulfilled.
>>
>> `new Promise(function (resolve, reject, cancel) {});` is the dumbest idea
>> I could have now beside `new Promise(function (resolve, reject)
>> {}).on('cancel', cancelback).then(whatever)` one
>>
>> Anyway, this would deserve IMO a thread a part but I hope this topic will
>> be discussed at some point.
>>
>> Best Regards
>
>
>
> I agree w/ Scott re: regularity of flow control, and I'd be particularly
> uneasy if a `cancel` method on a promise had any impact on upstream
> handlers. But ISTM something like this could be made to work (even if it
> looks a bit silly):
>
> ```js
> var cancelled;
> var never = new Promise(function () {});
> Promise.delay(100/*ms*/).then(function(value) {
>     return cancelled ? never : value;
> }, function (error) {
>     return cancelled ? never : throw error;
> });
> function cancel() { cancel = true };
> ```
>
> This could be cleaned up into a cancellation helper to quash downstream
> promises (this kind of utility would be a good use case for an `always`
> method if one isn't yet spec'd).
>
> Though I do wonder what happens to promises like these that get dropped on
> the floor? Will downstream handlers be GC'd? Is this specified in any way? I
> imagine dev tools want to warn about these kinds of promises — it may be
> helpful to have a way to signal that a promise was intentionally quashed.


More information about the es-discuss mailing list