首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Service worker使js运行两次

Service worker使js运行两次
EN

Stack Overflow用户
提问于 2018-10-26 20:10:41
回答 2查看 1.7K关注 0票数 1

我实现了来自pwabuilder.com的服务工作者,它工作得很好

问题是,即使浏览器在线,服务工作器也会运行,因此每个js函数都会运行两次,一次来自服务工作器,另一次来自我的其他js文件。

在运行js函数之前,我应该检查它是否是活动的服务工作者,或者当浏览器在线时,我应该以某种方式确保该服务工作者没有运行吗?

这是我在主索引文件中运行的代码

代码语言:javascript
复制
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如下所示:

代码语言:javascript
复制
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;
            });
        });
    })
);
});
EN

回答 2

Stack Overflow用户

发布于 2019-01-06 00:08:16

一旦注册、安装和激活,

服务工作者就可以全天候工作

Service workers是事件驱动的,它们的主要用途是充当缓存代理__、处理网络请求存储content以供脱机使用。其次是处理push messaging__。

我相信您明白,为了充当缓存代理,服务工作者将运行,而不管应用程序是在线还是离线。您需要考虑各种缓存方案。

很难为所提到的“每个js函数运行两次”提供确切的解决方案。

我怀疑所有的JS函数都会运行两次。这似乎是依赖于实现的。

服务工作者的作用域不能高于其自己的路径,默认情况下,它将控制服务工作者作用域下的所有资源,也可以限制此作用域。

代码语言:javascript
复制
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');}) }));

我希望上面的内容至少能帮助你找到你所面临的问题。

干杯,祝您编码快乐!

票数 2
EN

Stack Overflow用户

发布于 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>,如果有,您可能希望在没有它的情况下运行测试。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53008454

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档