Re: [ServiceWorker] Fetch API respondWith's implicit RETURN (#844)

> 1) Check cache for a hit and retrieve it
> 2) Fetch from network Request URL, if error go to cache-hit
> 3) Start off a timer that if gets in first will respond with a cache-hit
>
> It is also makes sure to update the cache even after the request has been responded to with a cache-hit. So, to me, the cache should be as up to date as possible.

I think this achieves what you're trying to do:

```js
self.addEventListener('fetch', event => {
  const cacheResponsePromise = caches.match(event.request);
  const networkFetchPromise = fetch(event.request);

  // # Populating the cache from the network
  // WARNING: by adding all responses into the cache like this, you'll run out
  // of space pretty quickly, you should restrict the URLs you do this for, or clean
  // the cache at some points
  event.waitUntil(
    networkFetchPromise.then(response => {
      // clone the response, because we're going to use it twice
      const responseClone = response.clone();
      
      return caches.open('my-cache-name').then(cache => {
        return cache.put(event.request, responseClone);
      });
    })
  );

  // # Responding to the request
  event.respondWith(
    // race the network and a timeout
    Promise.race([
      networkFetchPromise,
      new Promise((_, reject) => {
        setTimeout(() => reject(Error('Timeout')), 2000);
      })
      // if this times out or rejects, try the cacheā€¦
    ]).catch(() => cacheResponsePromise).then(response => {
      // if the cache has no match, defer to the network (without a timeout)
      // Note: you didn't say you wanted this, but it seems to make sense,
      // a slow network response is better than no response.
      return response || networkFetchPromise;
    })
  );
});
```

> You were right about the CATCH forcing a resolve but for the life of me WHY?

A promise is a async representation of try/catch, and this is how try/catch works. See http://jsbin.com/vuhawa/edit?js,console - the function returns undefined rather than throwing, because the error has been caught by a catch clause.

The same thing happens with promises: 

```js
const a = Promise.reject(Error('Broken'));
const b = a.catch(() => "Hello");
```

`a` rejects with an error, but `b` resolves with `"Hello"`.

> Money's on meningitis

Ooof, here's hoping for a speedy recovery.

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

Received on Sunday, 13 March 2016 12:24:00 UTC