我实现了来自pwabuilder.com的服务工作者,它工作得很好
问题是,即使浏览器在线,服务工作器也会运行,因此每个js函数都会运行两次,一次来自服务工作器,另一次来自我的其他js文件。
在运行js函数之前,我应该检查它是否是活动的服务工作者,或者当浏览器在线时,我应该以某种方式确保该服务工作者没有运行吗?
这是我在主索引文件中运行的代码
if (navigator.serviceWorker.controller) {
//console.log('[PWA Builder] active service worker found, no need to register')
} else {
//Register the ServiceWorker
navigator.serviceWorker.register('pwabuilder-sw.js', {
scope: './'
}).then(function (reg) {
//console.log('Service worker has been registered for scope:' + reg.scope);
});
}pwabuilder-sw.js如下所示:
self.addEventListener('install', function (event) {
var indexPage = new Request('');
event.waitUntil(
fetch(indexPage).then(function (response) {
return caches.open('pwabuilder-offline').then(function (cache) {
//console.log('[PWA Builder] Cached index page during Install' + response.url);
return cache.put(indexPage, response);
});
}));
});
//If any fetch fails, it will look for the request in the cache and serve it from there first
self.addEventListener('fetch', function (event) {
var updateCache = function (request) {
return caches.open('pwabuilder-offline').then(function (cache) {
return fetch(request).then(function (response) {
//console.log('[PWA Builder] add page to offline' + response.url);
return cache.put(request, response);
});
});
};
event.waitUntil(updateCache(event.request));
event.respondWith(
fetch(event.request).catch(function (error) {
//Check to see if you have it in the cache
//Return response
//If not in the cache, then return error page
return caches.open('pwabuilder-offline').then(function (cache) {
return cache.match(event.request).then(function (matching) {
var report = !matching || matching.status === 404 ? Promise.reject('no-match') : matching;
return report;
});
});
})
);
});发布于 2019-01-06 00:08:16
一旦注册、安装和激活,
服务工作者就可以全天候工作
Service workers是事件驱动的,它们的主要用途是充当缓存代理__、处理网络请求和存储content以供脱机使用。其次是处理push messaging__。
我相信您明白,为了充当缓存代理,服务工作者将运行,而不管应用程序是在线还是离线。您需要考虑各种缓存方案。
很难为所提到的“每个js函数运行两次”提供确切的解决方案。
我怀疑所有的JS函数都会运行两次。这似乎是依赖于实现的。
服务工作者的作用域不能高于其自己的路径,默认情况下,它将控制服务工作者作用域下的所有资源,也可以限制此作用域。
navigation.serviceWorker.register(
'/pwabuilder-sw.js', { //SW located at the root level here
scope: '/app/' //to control all resource accessed form within path /app/
}
);我相信来自pwabuilder.com的脚本确实试图缓存所有资源,甚至不应该缓存的资源,比如POST请求。您可能需要根据您使用的资源类型修改缓存策略。
这里没有简单的解决方案,也没有简单的答案。
通常,您可以使用服务工作线程以下列方式之一缓存资源:
self.addEventListener('fetch',(event) => { event.responseWith( caches.match(event.request) .then(( response ) => { return response || fetch(event.request);}) );});
//适用于更新频繁的资源//不利于中间层和慢速连接self.addEventListener('fetch',(event) => { event.responseWith( fetch(event.request).catch(() => { return caches.match(event.request);} );});
//先缓存后网络(1)(同时向缓存和网络发送请求)//先展示缓存的版本,当网络数据到达时再更新页面var networkDataReceived = false;var networkUpdate = fetch('/data.json') .then((response) => { return response.json();}).then(( data ) => { networkDataReceived = true;updatePage(data);});//缓存然后网络(2) caches.match('/data.json') .then ((response) => { return response.json();}).then((data) => { if (!networkDataReceived) { updatePage(data);} }).catch(() => { return networkUpdate;});
self.addEventListener('fetch',(event) => { event.responseWith( caches.match(event.request) .then(( response ) => { return response || fetch(event.request);}).catch(() => { return caches.match('offline.html');}) }));
我希望上面的内容至少能帮助你找到你所面临的问题。
干杯,祝您编码快乐!
发布于 2020-05-21 03:39:03
React添加了这个React.strictMode HOC,它运行两次应用程序的某些部分,如类组件构造函数、呈现和shouldComponentUpdate方法。
检查文档:
https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects。
看看您的index.js文件的顶部是否有<React.StrictMode>,如果有,您可能希望在没有它的情况下运行测试。
https://stackoverflow.com/questions/53008454
复制相似问题