- From: Joshua Bell <notifications@github.com>
- Date: Fri, 19 Feb 2016 15:30:43 -0800
- To: slightlyoff/ServiceWorker <ServiceWorker@noreply.github.com>
- Message-ID: <slightlyoff/ServiceWorker/issues/836/186450287@github.com>
The best I could come up with that approximates the original desired semantics - multiple cooperating handlers asynchronously decide if they are the one that will service the request, and have unfettered access to the `fetch` event - is something like the following. Like @mkruisselbrink I'm relying on the fact that multiple handlers see the same `Event` object and can decorate it. ```js function Helper(event) { var promises = [], count = 0, resolve; this.response = new Promise(r => resolve = r); this.add = function(p) { p.then( r => resolve(r), () => { if (++count === promises.length) resolve(fetch(event.request)); }); }; } // Multiple of these allowed self.addEventListener('fetch', event => { if (!event.helper) event.helper = new Helper(event); event.helper.add(new Promise((resolve, reject) => { self.caches.match(event.request).then(response => { if (response) resolve(response); else reject(); }).catch(reject); })); event.respondWith(event.helper.response); }); ``` I believe this has a race, though: if the first handler's cache check resolves before the second event handler is run, the Helper will conclude all associated Promises have completed. That could be addressed with a `setTimeout(..., 0)`, or maybe we can't run microtasks during event dispatch and it's moot. That's an awful lot of boilerplate per handler, though. So I agree that middleware is probably cleanest. If the handlers add Request → Promise<Response> functions to a collection (`self.fetchHandlers`, say) then the actual fetch handler can "race" them all, ignoring ones that reject. If all reject, it falls back to `fetch(event.request)` --- Reply to this email directly or view it on GitHub: https://github.com/slightlyoff/ServiceWorker/issues/836#issuecomment-186450287
Received on Friday, 19 February 2016 23:31:11 UTC