PWA(Progressive Web App)入门系列:Sync 后台同步
前言
当我们在一些地下停车场,或者在火车上、电梯等无法避免的信号不稳定的场所,使用网站应用处理一些表单操作或者上传数据的操作时,面临的将是网络连接错误的响应,使用户的操作白费。
而此刻 PWA 的 Sync API 就很好的解决了这个问题,让用户处理一些数据上传的操作时,无需关系网络环境,所有相关操作均会完成。Sync API 也是 PWA 离线里面的重要一环,下面就说一块。
SyncManager API
SyncManager 接口提供了用于注册和获取 Sync 注册的接口。Sync 是一个简单且非常实用的功能。
通过 ServiceWorkerRegistration 接口的 sync 进行获取:
navigator.serviceWorker.ready.then(reg => {console.log(reg.sync)
})
方法
SyncManager.register
用于注册一个 sync tag,tag 按照自己的需求设置。
语法:
SyncManager.register(DOMString tag).then(function(void) { ... })
返回 void 的 Promise。
SyncManager.getTags
用于获取已注册且未完成的 sync tag(完成后的 sync tag 会自动从此列表中删除)。
语法:
SyncManager.getTags().then(function(tags[]) { ... })
返回注册 syn tag 的字符串数组的 Promise。
事件
onsync
注册后的 Sync tag 会触发 ServiceWorkerGlobalScope 下的 onsync 事件。
此事件值包含两个属性:
tag
:返回触发此次事件的注册 Sync tag 的 tag 值。lastChance
:如果浏览器在尝试多次后还未成功,当 lastChance 为true
时表示不再尝试,且此次 sync tag 删除。
流程
从注册一个 Sync tag 到这个 Sync tag 完成,会经历三个阶段:
- Registered sync:注册 sync。
- Dispatched sync event:发出 sync 事件。
- Sync completed:Sync 完成。
SyncManager.register(tag)
后,会立即注册 sync,并将注册后的 sync tag 放入 sync 的注册列表中(可以通过SyncManager.getTags()
获取到),然后会判断当前的网络环境,只有网络在线的情况下,注册的 Sync 才会发出 sync 事件,然后当 SyncEvent.waitUntil()
中 Promise 为 reject 时将会周期性的触发 onsync 事件,直到不为 reject 才会完成 Sync tag,然后将相关 tag 清除。
在 Chrome 下,当 SyncEvent.waitUntil()
中的参数值一直为 Promise reject 时,会最多触发三次 onsync 事件,每次的周期时间至少为 5 分钟。
注意:sync 事件中的处理结果必须放在 SyncEvent.waitUntil() 中,否则会立即完成 Sync。
注意:上图中的重试次数和周期时间是 Chrome 环境下的体现,具体次数和周期标准中未规范,可以 e.lastChance 来判读,处理最后一次的相关逻辑。
可以通过 DevTools 里的 Background Services 查看 Sync 的执行过程:
使用场景
SyncManager 本身只是一个简单的 API,sync 事件中也只有两个只读属性,所以基于 Sync 来做的同步数据,比较好的方式搭配 IndexDB 来实现,下面两个场景也是基于 IndexDB。
1. 完全 Sync 化数据请求传输
这种场景下,相关场景的数据请求先写入 IndexDB 中,然后注册 Sync,在 onsync 中根据相关 tag 来处理 IndexDB 中的数据请求。
下面是一个聊天应用的场景
index.html:
btnSend.addEventListener('click', async () => {await db.add('chatList', { msg, time, useId});reg = await navigator.serviceWorker.ready;reg.sync.register('send_chat');
})
sw.js
self.addEventListener('sync', e => {e.tag == 'send_chat' && e.waitUntil(new Promise.then(async (res, rej) => {var allData = await db.getAll('chatList');return Promise.all(allData.map(data => fetch(data)));}))
})
2. 失败请求的 Sync 化
这个场景可以针对于某些特定请求,先让它正常发送网络请求,如果失败则将失败的请求放到相关的 IndexDB 中,并设定这条网络请求可尝试的有效期,有效期内均会重拾。
关于 sync 的周期上面也说过,在 Chrome 下最多尝试三次,本场景下的这种需求,需要相关的 sync tag 一直处理可用状态,所以需要对这一层进行修改满足需求。
例如点赞场景
index.html
btnLike.addEventListener('click', () => {reg = await navigator.serviceWorker.ready;reg.sync.register('like’);fetch(data).catch(e => {db.add('likeList', {data, lastTime: 12938749138}); // 有效期时间戳})
})
sw.js
self.addEventListener("sync", e => {if (e.tag == "send_chat") {e.waitUntil(new Promise.then(async (res, rej) => {while (db.get("likeList")[0]) {var data = db.get("likeList")[0];try {if(data.lastTime > Date.now()) {db.remove('likeList', data)} else {await fetch(data);db.remove('likeList', data)} } catch (err) {if(e.lastChance == true) { // 如果最后一次尝试机会,则重新注册,保证一直有效self.registration.sync.register('like')}}}}));}
});
注意:上面代码中的 db 为模拟的伪代码。
通过 Sync API 的支持,网站应用可以较大的离线化,提升用户的体验度和应用的可靠性。这样用户在网络连接失败的情况下也能上传表单、点赞评论文章、发送消息等等,为用户带来积极的影响。也意味着 Web 应用更加接近原生应用的体验效果。
博客名称:王乐平博客
CSDN博客地址:http://blog.csdn.net/lecepin
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。
PWA(Progressive Web App)入门系列:Sync 后台同步相关推荐
- PWA(Progressive Web App)入门系列:(一)PWA简介
前言 PWA做为一门Google推出的WEB端的新技术,好处不言而喻,但目前对于相关方面的知识不是很丰富,这里我推出一下这方面的入门教程系列,提供PWA方面学习. 什么是PWA PWA全称Progre ...
- PWA(Progressive Web App)入门系列:(三)PWA关键技术Manifest
前言 前面说过,让Web App能够达到Native App外观体验的主要实现技术就是PWA中的manifest技术,本章会详细说明manifest的实现,及各个参数的具体含义,还将了解如何定义Web ...
- PWA(Progressive Web App)入门系列:消息通讯
前言 serviceWorker 的能力决定它要处理的事情,网站页面的部分逻辑处理会转移到 serviceWorker 层进行处理,这里就要页面层和 serviceWorker 层进行交互来实现消息通 ...
- PWA(Progressive Web App)入门系列:安装 Web 应用
前言 在传统的 Web 应用中,通常只能通过在浏览器的地址栏里输入相应的网址才能进行访问,或者把网页地址创建到桌面上通过点击,然后在浏览器里打开. 传统模式下,图标.启动画面.主题色.视图模式.屏幕方 ...
- PWA(Progressive Web App)入门系列:Push
前言 很多时候,原生应用会通过一些消息推送来唤起用户的关注,增加驻留率.网页该怎么做呢?有没有类似原生应用的推送机制?推送功能又能玩出什么花样呢? Push API Push API 给与了 Web ...
- PWA(Progressive Web App)入门系列:Cache Storage Cache
前言 目前浏览器的存储机制有很多,如:indexedDB.localStorage.sessionStorage.File System API.applicationCache 等等,那为什么又制定 ...
- PWA(Progressive Web App)入门系列:(四)Promise
前言 这一章说一下ES6的Promise对象.为什么要在PWA系列的文章中讲Promise呢?因为PWA中的许多技术API中都是以Promise返回的方式返回的,为了对后续章节中PWA技术API更好的 ...
- PWA(Progressive Web App)入门系列:(二)相关准备
前言 在上一章中,对PWA的相关概念做了基本介绍,了解了PWA的组成及优势.为了能够更快的进入PWA的世界,这一章主要对在PWA开发中,需要注意的问题,运行的环境及调试工具做介绍说明. 浏览器要求 因 ...
- PWA(Progressive Web App)入门系列:Notification
前言 在很多场景下,需要一种通知的交互方式来提醒用户,传统方式下可以在页面实现一个 Dialog,或通过修改网页的 title 来实现消息的通知.然而传统的实现存在着一定的不足,在网页最小化的情况下, ...
最新文章
- 任正非:我若贪生怕死,何来让你们去英勇奋斗
- Mysql数据库大表归档操作
- 解决MySQL事务未提交导致死锁报错 避免死锁的方法
- [视频教程] 如何在docker环境下的纯净ubuntu系统中安装最新版nginx
- FullCalendar插件月视图正常显示周视图不正常显示问题解决方法
- 智慧交通day02-车流量检测实现06:目标估计模型-卡尔曼滤波
- nodejs中处理回调函数的异常
- Kafka 优化参数 unclean.leader.election.enable
- [C++/CLI]在栈上声明Reference Type
- TortoiseSVN 使用详细步骤(三):安装
- SimpleDateFormat-多线程问题
- python萤火虫算法_一种萤火虫算法优化神经网络的短期负荷预测方法与流程
- 苹果显示器(Apple Cinema Display)连接Windows的亮度调节方法(Win10可用)
- 中文编程语言实现:翻译器
- 【角度刁钻】如果把线程当作一个人来对待,秒懂
- oracle数据文件头损坏6,恢复数据库时遇到数据文件头损坏 | 信春哥,系统稳,闭眼上线不回滚!...
- NLP常见词/典汇总
- linux打开80端口及80端口占用解决办法
- java 调用 mahout_(转)Mahout使用入门
- SQL Server2008下载链接以及安装教程