我从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;
});
});
})
);
});
服务人员在注册、安装和激活后一直工作
服务工作者是事件驱动的,他们的主要用途是充当缓存代理,处理网络请求和存储内容以供离线使用。其次是处理推送消息
我相信您理解,为了充当缓存代理,无论应用程序是联机还是脱机,服务工作者都将运行。您需要考虑各种缓存场景。
很难为上述问题提供确切的解决方案:"每个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); }) ); });
网络回退到缓存
//Good for resources that update frequently //Bad for Intermittend and slow connections self.addEventListener('fetch', (event) => { event.responseWith( fetch(event.request).catch(() => { return caches.match(event.request); }) ); });
缓存然后网络
//Cache then network(1) (send request to cache and network simultaneousely) //show cached version first, then update the page when the network data arrives var networkDataReceived = false; var networkUpdate = fetch('/data.json') .then((response) => { return response.json(); }).then((data) => { networkDataReceived = true; updatePage(data); }); //Cache then network(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'); }) ) });
我希望以上内容至少能帮助您找到您面临的确切问题
干杯!
React添加了这个React.strectMode HOC,它运行两次应用程序的某些部分,如类组件构造函数、render和shouldComponentUpdate方法
检查文档:
https://reactjs.org/docs/strict-mode.html#detecting-意想不到的副作用。
看看你的index.js
文件顶部是否有<React.StrictMode>
,如果有,你可能想在没有它的情况下运行测试。