服务人员可以做哪些Web工作人员不能做的事情?或者相反?
Web工作人员似乎是服务工作人员功能的子集。这是否正确?
它们的用途有很大的不同:
网络工作者
Web Workers为Web内容提供了一种在后台线程中运行脚本的简单方法。工作线程可以执行任务,而不 干扰用户界面。此外,它们还可以执行I/O 使用XMLHttpRequest(尽管responseXML和channel属性 始终为空)。创建后,工作线程可以将消息发送到 通过向事件发布消息来创建它的JavaScript代码 由代码指定处理程序(反之亦然)。
Web Workers为Web内容提供了一种在后台线程中运行脚本的简单方法。工作线程可以执行任务,而不 干扰用户界面。此外,它们还可以执行I/O 使用XMLHttpRequest(尽管responseXML和channel属性 始终为空)。创建后,工作线程可以将消息发送到 通过向事件发布消息来创建它的JavaScript代码 由代码指定处理程序(反之亦然)
源-使用Web Workers
服务人员
服务人员本质上充当位于Web之间的代理服务器 应用程序、浏览器和网络(如果可用)。他们是 旨在(除其他事项外)能够创建有效的 离线体验,拦截网络请求并获取 根据网络是否可用而采取适当的措施,以及 更新的资产驻留在服务器上。它们还将允许访问 推送通知和后台同步API.
来源-服务人员API
因此,Web工作人员可以方便地运行昂贵的脚本,而不会导致用户界面冻结。 而服务人员则可用于修改网络请求的响应(例如,在构建离线应用程序时)。
布克西的回答是正确的,但在我看来,它没有回答最初的问题,即:服务人员可以做哪些Web工作人员不能做的事情?或者相反?
它们的生命周期和每个源可以拥有的实例数量存在根本差异。简而言之:
| Web Workers | Service Workers | |--------------|--------------|------------------| | Instances | Many per tab | One for all tabs | | Lifespan | Same as tab | Independent | | Intended use | Parallelism | Offline support |
布克西的答案基本上是表格的最后一排。来源:我从诺兰·劳森(Nolan Lawson)的揭开网络工作者和服务人员的神秘面纱中获得了这张表,从幻灯片35开始。
特别是,下面是生成和终止Web Workers的方式:
使用Web Workers
而服务人员有自己的生命周期,这是公认的“最复杂的部分”:
服务人员生命周期
_ABC两者之间的_为0(预期用途的结果)。
过去,浏览器支持有一个巨大的差异:直到11.3(2018年3月29日),服务人员在iOS版Safari中根本不可用,请参阅我可以使用服务人员吗?。相比之下,Web Workers在2012年已经有了更好的浏览器支持:我可以使用Web Workers吗?
如果你必须支持IE11,你只能使用Web Workers:IE11没有Service Workers,并且显然IE11支持将于2025年10月14日终止。
在不同浏览器中,它们的API支持存在细微差别,请参阅HTML5工人测试(也由Nolan Lawson编写)。在特定的浏览器中,一种工作者可能支持特定的API调用,而另一种工作者则不支持。访问该页面并测试您自己的浏览器!
服务人员是浏览器和网络之间的代理。通过拦截文档发出的请求,服务人员可以将请求重定向到缓存,从而实现脱机访问。
/* main.js */ navigator.serviceWorker.register('/service-worker.js'); /* service-worker.js */ // Install self.addEventListener('install', function(event) { // ... }); // Activate self.addEventListener('activate', function(event) { // ... }); // Listen for network requests from the main document self.addEventListener('fetch', function(event) { // ... });
Web Workers是通用脚本,它使我们能够从主线程中卸载处理器密集型工作。
/* main.js */ // Create worker const myWorker = new Worker('worker.js'); // Send message to worker myWorker.postMessage('Hello!'); // Receive message from worker myWorker.onmessage = function(e) { console.log(e.data); }
原始POST这里