我从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;
});
});
})
);
});
答案 0 :(得分:0)
服务人员一经注册,安装和激活,就可以一直工作
服务人员是事件驱动的,其主要用途是充当缓存代理,处理网络请求和存储内容可以离线使用。其次,处理推送消息。
我相信您了解,为了充当缓存代理,无论应用程序是联机还是脱机,服务工作者都将运行。您需要考虑各种缓存方案。
很难为上述问题提供确切的解决方案:“每个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');
})
)
});
我希望以上内容至少可以帮助您找到您所面临的确切问题。
干杯和快乐!
答案 1 :(得分:0)
React添加了此React.strictMode HOC,它可以运行应用程序某些特定部分的两倍,例如类组件构造函数,render和shouldComponentUpdate方法。
检查文档:
https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects。
查看<React.StrictMode>
文件顶部是否有index.js
,如果是,则可能需要运行没有它的测试。