Service Worker

Service Worker

简介

Service worker 是后台运行的一个 JavaScript 脚本。它由前台页面的 JavaScript 脚本新建,运行在独立的线程。它是异步的,不会造成页面的堵塞,可以发出通知(push notification),但拿不到 DOM。它要求页面必须使用 HTTPS 协议。

Service Worker 一共有6种状态。

  • parsed
  • installing
  • installed
  • activating
  • activated
  • redundant

登记Service Worker。

/* In main.js */
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('./sw.js')
  .then(function(registration) {
    console.log("Service Worker Registered", registration);
  })
  .catch(function(err) {
    console.log("Service Worker Failed to Register", err);
  })
}

一旦登记成功,Service Worker的状态就变成了parsed

然后,浏览器尝试安装Service Worker脚本,这时它的状态就变成了installing

/* In main.js */
navigator.serviceWorker
.register('./sw.js')
.then(function(registration) {
  if (registration.installing) {
    // Service Worker is Installing
  }
})

一旦进入安装阶段,Service Worker脚本会接收到一个install事件。这个事件的回调函数里面,可以缓存静态文件。

/* In sw.js */
var cacheName = 'your-first-service-worker';
var urlsToCache = [
  '/',
  'css/tachyons.min.css',
  'img/andre-benz-248755.jpg',
  'img/andre-benz-250740.jpg',
  'img/andre-benz-256762.jpg',
  'img/redd-angelo-230297.jpg'
];

self.addEventListener('install', function(event) {
    // Perform install steps
    event.waitUntil(
        caches.open(cacheName)
        .then(function(cache) {
            console.log('Opened cache');
            return cache.addAll(urlsToCache);
        })
    );
});

上面代码中,事件对象有一个event.waitUntil()方法,只有这个方法内部的 Promise 变成resolved以后,installing事件才会成功。如果Promise变成rejectedinstalling事件就会失败,Service Worker 变成redundant状态。

/* In sw.js */
self.addEventListener('install', function(event) {
  event.waitUntil(
    Promise.reject(); // Failure
  );
});

如果安装成功,Service Worker就变成installed状态,或者也叫waiting状态。这时,Service Worker是有效的,但还没有被激活。它还不受当前文档控制,而是等待接受控制的状态。

主脚本之中可以检查,是否处于waiting状态。

/* In main.js */
navigator.serviceWorker.register('./sw.js').then(function(registration) {
  if (registration.waiting) {
    // Service Worker is Waiting
  }
})

这时可以通知用户升级版本,或者为他们自动更新。

以下几种情况,Service Worker会进入activating状态。

  • 当前没有活跃的Worker
  • Service Worker脚本里面,调用了self.skipWaiting()方法
  • 用户离开当前页面,因此释放了前一个活跃的worker
  • 经过一段时间,前一个活跃的worker已经释放

进入activating状态时,Service Worker 脚本会接收到active事件,通常在这个事件的回调函数里面清除旧缓存。

/* In sw.js */
self.addEventListener('activate', function(event) {
  event.waitUntil(
    // Get all the cache names
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        // Get all the items that are stored under a different cache name than the current one
        cacheNames.filter(function(cacheName) {
          return cacheName != currentCacheName;
        }).map(function(cacheName) {
          // Delete the items
          return caches.delete(cacheName);
        })
      ); // end Promise.all()
    }) // end caches.keys()
  ); // end event.waitUntil()
});

上面代码中,也有一个event.waitUntil()方法,只有它里面的Promise变成resolved,激活才能成功。否则,就会激活失败,Service Worker变成redundant

如果激活成功,Service Worker就变成active状态,这时Service Worker会完全控制文档。我们可以这样检查是否进入这个状态。

/* In main.js */
navigator.serviceWorker.register('./sw.js').then(function(registration) {  
    if (registration.active) {
        // Service Worker is Active
    }
})

一旦Service Worker激活,它就能处理fetch 和 message 事件。

/* In sw.js */

self.addEventListener('fetch', function(event) {  
  // Do stuff with fetch events
});

self.addEventListener('message', function(event) {  
  // Do stuff with postMessages received from document
});

由于以下原因,Service Worker会变成redundant状态。

  • installing 事件失败
  • activating 事件失败
  • 一个新的Service Worker取代了当前活跃的Service worker

用户发出请求时,会触发fetch事件。

// Fetch the contents and reply with cache
self.addEventListener('fetch', function (event) {
    event.respondWith(
        caches.match(event.request)
        .then(function(response) {
            // Cache hit - return response
            if (response) {
              return response;
            }
            return fetch(event.request);
        })
    );
});

参考链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值