前言

当我们在一些地下停车场,或者在火车上、电梯等无法避免的信号不稳定的场所,使用网站应用处理一些表单操作或者上传数据的操作时,面临的将是网络连接错误的响应,使用户的操作白费。

而此刻 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 后台同步相关推荐

  1. PWA(Progressive Web App)入门系列:(一)PWA简介

    前言 PWA做为一门Google推出的WEB端的新技术,好处不言而喻,但目前对于相关方面的知识不是很丰富,这里我推出一下这方面的入门教程系列,提供PWA方面学习. 什么是PWA PWA全称Progre ...

  2. PWA(Progressive Web App)入门系列:(三)PWA关键技术Manifest

    前言 前面说过,让Web App能够达到Native App外观体验的主要实现技术就是PWA中的manifest技术,本章会详细说明manifest的实现,及各个参数的具体含义,还将了解如何定义Web ...

  3. PWA(Progressive Web App)入门系列:消息通讯

    前言 serviceWorker 的能力决定它要处理的事情,网站页面的部分逻辑处理会转移到 serviceWorker 层进行处理,这里就要页面层和 serviceWorker 层进行交互来实现消息通 ...

  4. PWA(Progressive Web App)入门系列:安装 Web 应用

    前言 在传统的 Web 应用中,通常只能通过在浏览器的地址栏里输入相应的网址才能进行访问,或者把网页地址创建到桌面上通过点击,然后在浏览器里打开. 传统模式下,图标.启动画面.主题色.视图模式.屏幕方 ...

  5. PWA(Progressive Web App)入门系列:Push

    前言 很多时候,原生应用会通过一些消息推送来唤起用户的关注,增加驻留率.网页该怎么做呢?有没有类似原生应用的推送机制?推送功能又能玩出什么花样呢? Push API Push API 给与了 Web ...

  6. PWA(Progressive Web App)入门系列:Cache Storage Cache

    前言 目前浏览器的存储机制有很多,如:indexedDB.localStorage.sessionStorage.File System API.applicationCache 等等,那为什么又制定 ...

  7. PWA(Progressive Web App)入门系列:(四)Promise

    前言 这一章说一下ES6的Promise对象.为什么要在PWA系列的文章中讲Promise呢?因为PWA中的许多技术API中都是以Promise返回的方式返回的,为了对后续章节中PWA技术API更好的 ...

  8. PWA(Progressive Web App)入门系列:(二)相关准备

    前言 在上一章中,对PWA的相关概念做了基本介绍,了解了PWA的组成及优势.为了能够更快的进入PWA的世界,这一章主要对在PWA开发中,需要注意的问题,运行的环境及调试工具做介绍说明. 浏览器要求 因 ...

  9. PWA(Progressive Web App)入门系列:Notification

    前言 在很多场景下,需要一种通知的交互方式来提醒用户,传统方式下可以在页面实现一个 Dialog,或通过修改网页的 title 来实现消息的通知.然而传统的实现存在着一定的不足,在网页最小化的情况下, ...

最新文章

  1. 任正非:我若贪生怕死,何来让你们去英勇奋斗
  2. Mysql数据库大表归档操作
  3. 解决MySQL事务未提交导致死锁报错 避免死锁的方法
  4. [视频教程] 如何在docker环境下的纯净ubuntu系统中安装最新版nginx
  5. FullCalendar插件月视图正常显示周视图不正常显示问题解决方法
  6. 智慧交通day02-车流量检测实现06:目标估计模型-卡尔曼滤波
  7. nodejs中处理回调函数的异常
  8. Kafka 优化参数 unclean.leader.election.enable
  9. [C++/CLI]在栈上声明Reference Type
  10. TortoiseSVN 使用详细步骤(三):安装
  11. SimpleDateFormat-多线程问题
  12. python萤火虫算法_一种萤火虫算法优化神经网络的短期负荷预测方法与流程
  13. 苹果显示器(Apple Cinema Display)连接Windows的亮度调节方法(Win10可用)
  14. 中文编程语言实现:翻译器
  15. 【角度刁钻】如果把线程当作一个人来对待,秒懂
  16. oracle数据文件头损坏6,恢复数据库时遇到数据文件头损坏 | 信春哥,系统稳,闭眼上线不回滚!...
  17. NLP常见词/典汇总
  18. linux打开80端口及80端口占用解决办法
  19. java 调用 mahout_(转)Mahout使用入门
  20. SQL Server2008下载链接以及安装教程

热门文章

  1. FTP文件共传输服务
  2. mysql导入导出数据
  3. 找到一个比较熟悉Go语言的国内博客
  4. Firefox 5 公开测试下载
  5. 实验二十四、OSPF 在NBMA 环境中点到点的配置
  6. Java—BIO模型
  7. leetcode459. 重复的子字符串
  8. 别把“运气”当“实力”
  9. python篇第6天【数据类型】
  10. 记一次Java AES 加解密 对应C# AES加解密 的一波三折