Some have suggested 'fetch' shouldn't be an event, and should be another kind of callback where you return a response/promise to indicate interest in the event.
this.onfetch = function(event) {
event.respondWidth(
caches.match(event.request).catch(function() {
return fetch('kittens.jpg');
})
);
};
// vs
fetchIntercept(function(requestDetails) {
return caches.match(requestDetails.request).catch(function() {
return fetch('kittens.jpg');
});
});
Why it should be an event:
Why it shouldn't be an event:
respondWith calls preventDefault and stopImmediatePropogation, is this breaking the model?@Hixie @stefanpenner @annevk - any further cases against?
The SW design adds functionality to events, whereas they are designed to be a cheap notification feature for state/date.
Events are also not supposed to have side effects. (E.g. observing there are listeners.)
I think something like fetchHooks.add() / remove() / ... could work here. Not sure about the other "events" we have.
Same for oninstall and its waitUntil event method. I really feel these are strong code smells. We're using events to express a different pattern, here.
What we're looking at during installation is to carve a space in the algorithm itself for the developer to do stuff. That's a common design pattern: a template method. The dynamic characteristics of JavaScript allow us to define it in the instance object itself rather than need to subclass SW. The fact that it might need to be async just means that a call to it has to be wrapped using Promise.resolve, e.g. in pseudo js code:
if (this.setup) {
Promise.resolve(this.setup()).then(_nextStepOfTheAlgo);
} else {
_nextStepOfTheAlgo();
}
Which allows the developer to write:
this.setup = function() {
var shellResources = new Cache();
return shellResources.add(
"/app.html",
"/assets/v1/base.css",
"/assets/v1/app.js",
"/assets/v1/logo.png",
"/assets/v1/intro_video.webm",
).then(function() {
caches.set("shell-v1", shellResources);
});
};
There's a strong similarity for respondWith and I like Anne's suggestion to use an express.js inspired add method here. I look into this more once I'm back at my desk.
What is the design goal of these hooks? I can think of a few that change the design.
this.setup = is good.this.fetch = is good, and people can build "Express for service workers" which monopolizes the this.fetch = hook but then composes middleware which it inserts into the pipeline.e.waitUntil first, or alternately whose promise settles first.It might be different in each case. I agree that events + waitUntil is not great. But then again, it is not horrible, as long as the semantics are well-defined (i.e. the way in which they race).
Returning promises is pretty nice though, when it can be arranged...
This isn't changing. Closing.