[ServiceWorker] Allow respondWith() to be called asynchronously or allow some way to cancel the response. (#836)

Following the app shell architecture, we are providing WordPress Plugins able to cache content and shell separately. For them to collaborate we are providing an infrastructure that combine multiple service workers files which leads to the situation when having several fetch event handlers is possible.

Actually, one the handlers has this form:
```js
    event.respondWith(
      caches.match(onlyPath(request))
        .then(function(response) {
          // Cache hit - return the response from the cached version
          if (response) {
            console.log(
              '[fetch] Returning from ServiceWorker cache: ',
              event.request.url
            );
            return response;
          }
          // Not in cache - return the result from the live server
          // `fetch` is essentially a "fallback"
          return fetch(event.respondWith);
        }
      )
    );
```

But if I want to give the opportunity to other handlers for acting when there is no hit in the cache, I need some way to unset the _respond-with entered_ flag of the event. So I can do:
```js
    event.respondWith(
      caches.match(onlyPath(request))
        .then(function(response) {
          // Cache hit - return the response from the cached version
          if (response) {
            console.log(
              '[fetch] Returning from ServiceWorker cache: ',
              event.request.url
            );
            return response;
          }
          // Not in cache - allow other handlers to act
          return event.cancelResponse();
        }
      )
    );
```

The other option is to allow `.respondWith()` to be called asynchronously:
```js
    event.waitUntil(
      caches.match(onlyPath(request))
        .then(function(response) {
          // Cache hit - return the response from the cached version
          if (response) {
            console.log(
              '[fetch] Returning from ServiceWorker cache: ',
              event.request.url
            );
            event.respondWith(response); // we respond now we know there is a match
          }
          // Not in cache - do nothing and allow other handlers to act
        }
      )
    );
```

But this is not working. It results in an error saying:
```
Uncaught InvalidStateError: Failed to execute 'respondWith' on 'FetchEvent': The fetch event has already been responded to.
```

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

Received on Thursday, 18 February 2016 19:55:56 UTC