Re: [ServiceWorker] Returning a FetchPromise from fetch() (#625)

> ```js
> var p = fetch(url).then(r => r.json());
> p.abort();
> // aborts fetch for url and rejects promise so .json is never called
> // or if fetch already resolved:
> //   terminate the stream and therefore reject .json()
> ```

We were also contemplating leaving the promise forever-pending instead of rejecting it, if the fetch is in progress.

> ```js
> var p = fetch(url1).then(_ => fetch(url2));
> p.abort();
> // aborts fetch for url1 and rejects promise so url2 is never fetched
> // or if fetch(url1) already resolved:
> //   terminate the stream for url1
> //   abort the fetch for url2
> ```

The latter is not entirely clear. We could design it either way---return values are ignored, or return value abortion is supported.

Analogously would be the question:

```js
var p = FetchPromise.resolve(otherFetchPromise).abort();
```

Does abortion of `p` imply abortion of `otherFetchPromise`?

> ```js
> var p = fetch(url1).then(_ => wait(3000)).then(_ => fetch(url2));
> p.abort();
> // aborts fetch for url1 and rejects
> // or if fetch(url1) already resolved:
> //   terminate the stream for url1
> //   reject the 'wait' so url2 never fetches
> ```

Well, only if `wait` also returns a FetchPromise (or other abort-able promise). You can't just reject arbitrary promises.

> ```js
> // or if wait(3000) already resolved:
> //   terminate the stream for url1
> //   abort the fetch for url2
> ```

This comes down to the same question as above.

> ```js
> var p = Promise.resolve(fetch(url));
> p.abort();
> // undefined is not a function (fetchPromise has been casted to a normal promise)
> ```

Yes, definitely.

> If the above is right, we need a generic AbortablePromise, then a hook on that for specific abortion steps which FetchPromise would extend.

That's one approach. If we want that, someone's going to have to do the design for a generic AbortablePromise, which is going to be tricky. See e.g. last paragraph of https://esdiscuss.org/topic/aborting-an-async-function#content-9.

> For the above to work, .then() needs to add state (or an onabort callback) to the new promise to maintain the link back to the original fetch.

Sure, just define `then` appropriately. For example, here's one design: https://github.com/promises-aplus/cancellation-spec/issues/6; replace `this.constructor` with `this.constructor[Symbol.species]` since that code was written before species existed.

> // should this cause jsonPromise to abort?

This is the biggest issue with cancellable promises, IMO. Our current take is to make `then` fail when called twice on a single cancellable promise. That way you can use it like a normal promise in most cases (including `await`), but you cannot extract its value twice.


---
Reply to this email directly or view it on GitHub:
https://github.com/slightlyoff/ServiceWorker/issues/625#issuecomment-75341013

Received on Friday, 20 February 2015 23:52:42 UTC