From caa3e7dddcdf6814995b397861cfc63e821ce3a5 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Sat, 28 May 2022 16:20:52 +0800 Subject: [PATCH 1/3] AutoCorrect files/zh-cn/web/api/service_worker_api/ --- .../web/api/service_worker_api/index.html | 66 +++++++++---------- .../using_service_workers/index.html | 62 ++++++++--------- .../controller/index.html | 4 +- .../web/api/serviceworkercontainer/index.html | 18 ++--- .../register/index.html | 10 +-- 5 files changed, 80 insertions(+), 80 deletions(-) diff --git a/files/zh-cn/web/api/service_worker_api/index.html b/files/zh-cn/web/api/service_worker_api/index.html index 780ff8e5cd27c6..919b1d08ab5f16 100644 --- a/files/zh-cn/web/api/service_worker_api/index.html +++ b/files/zh-cn/web/api/service_worker_api/index.html @@ -16,27 +16,27 @@

Service worker 的概念和用法

-

Service worker是一个注册在指定源和路径下的事件驱动worker。它采用JavaScript控制关联的页面或者网站,拦截并修改访问和资源请求,细粒度地缓存资源。你可以完全控制应用在特定情形(最常见的情形是网络不可用)下的表现。

+

Service worker 是一个注册在指定源和路径下的事件驱动worker。它采用 JavaScript 控制关联的页面或者网站,拦截并修改访问和资源请求,细粒度地缓存资源。你可以完全控制应用在特定情形(最常见的情形是网络不可用)下的表现。

-

Service worker运行在worker上下文,因此它不能访问DOM。相对于驱动应用的主JavaScript线程,它运行在其他线程中,所以不会造成阻塞。它设计为完全异步,同步API(如XHRlocalStorage)不能在service worker中使用。

+

Service worker 运行在 worker 上下文,因此它不能访问 DOM。相对于驱动应用的主 JavaScript 线程,它运行在其他线程中,所以不会造成阻塞。它设计为完全异步,同步 API(如XHRlocalStorage)不能在 service worker 中使用。

-

出于安全考量,Service workers只能由HTTPS承载,毕竟修改网络请求的能力暴露给中间人攻击会非常危险。在Firefox浏览器的用户隐私模式,Service Worker不可用。

+

出于安全考量,Service workers 只能由 HTTPS 承载,毕竟修改网络请求的能力暴露给中间人攻击会非常危险。在 Firefox 浏览器的用户隐私模式,Service Worker 不可用。

-

注意:Service workers之所以优于以前同类尝试(如AppCache),是因为它们无法支持当操作出错时终止操作。Service workers可以更细致地控制每一件事情。

+

注意:Service workers 之所以优于以前同类尝试(如AppCache),是因为它们无法支持当操作出错时终止操作。Service workers 可以更细致地控制每一件事情。

-

注意:Service workers大量使用Promise,因为通常它们会等待响应后继续,并根据响应返回一个成功或者失败的操作。Promise非常适合这种场景。

+

注意:Service workers 大量使用Promise,因为通常它们会等待响应后继续,并根据响应返回一个成功或者失败的操作。Promise 非常适合这种场景。

注册

-

使用 {{domxref("ServiceWorkerContainer.register()")}} 方法首次注册service worker。如果注册成功,service worker就会被下载到客户端并尝试安装或激活(见下文),这将作用于整个域内用户可访问的URL,或者其特定子集。

+

使用 {{domxref("ServiceWorkerContainer.register()")}} 方法首次注册 service worker。如果注册成功,service worker 就会被下载到客户端并尝试安装或激活(见下文),这将作用于整个域内用户可访问的 URL,或者其特定子集。

下载、安装和激活

-

此时,你的服务工作者(service worker)将遵守以下生命周期:

+

此时,你的服务工作者 (service worker) 将遵守以下生命周期:

  1. 下载
  2. @@ -44,52 +44,52 @@

    下载、安装和激活

  3. 激活
-

用户首次访问service worker控制的网站或页面时,service worker会立刻被下载。

+

用户首次访问 service worker 控制的网站或页面时,service worker 会立刻被下载。

-

之后,在以下情况将会触发更新:

+

之后,在以下情况将会触发更新:

-

无论它与现有service worker不同(字节对比),还是第一次在页面或网站遇到service worker,如果下载的文件是新的,安装就会尝试进行。

+

无论它与现有 service worker 不同(字节对比),还是第一次在页面或网站遇到 service worker,如果下载的文件是新的,安装就会尝试进行。

-

如果这是首次启用service worker,页面会首先尝试安装,安装成功后它会被激活。

+

如果这是首次启用 service worker,页面会首先尝试安装,安装成功后它会被激活。

-

如果现有service worker已启用,新版本会在后台安装,但不会被激活,这个时序称为worker in waiting。直到所有已加载的页面不再使用旧的service worker才会激活新的service worker。只要页面不再依赖旧的service worker,新的service worker会被激活(成为active worker)。

+

如果现有 service worker 已启用,新版本会在后台安装,但不会被激活,这个时序称为 worker in waiting。直到所有已加载的页面不再使用旧的 service worker 才会激活新的 service worker。只要页面不再依赖旧的 service worker,新的 service worker 会被激活(成为 active worker)。

-

你可以监听{{domxref("InstallEvent")}},事件触发时的标准行为是准备service worker用于使用,例如使用内建的storage API来创建缓存,并且放置应用离线时所需资源。

+

你可以监听{{domxref("InstallEvent")}},事件触发时的标准行为是准备 service worker 用于使用,例如使用内建的 storage API 来创建缓存,并且放置应用离线时所需资源。

-

还有一个activate事件,触发时可以清理旧缓存和旧的service worker关联的东西。

+

还有一个 activate 事件,触发时可以清理旧缓存和旧的 service worker 关联的东西。

-

Servcie worker可以通过 {{domxref("FetchEvent")}} 事件去响应请求。通过使用 {{domxref("FetchEvent.respondWith") }} 方法,你可以任意修改对于这些请求的响应。

+

Servcie worker 可以通过 {{domxref("FetchEvent")}} 事件去响应请求。通过使用 {{domxref("FetchEvent.respondWith") }} 方法,你可以任意修改对于这些请求的响应。

-

注意: 因为oninstallonactivate完成前需要一些时间,service worker标准提供一个waitUntil方法,当oninstall或者onactivate触发时被调用,接受一个promise。在这个 promise被成功resolve以前,功能性事件不会分发到service worker。

+

注意: 因为oninstallonactivate完成前需要一些时间,service worker 标准提供一个waitUntil方法,当oninstall或者onactivate触发时被调用,接受一个 promise。在这个 promise 被成功 resolve 以前,功能性事件不会分发到 service worker。

构建一个基本用例的完整教程,请阅读 使用 Service Workers

其他使用场景

-

Service workers也可以用来做这些事情:

+

Service workers 也可以用来做这些事情:

-

未来service workers能够用来做更多使web平台接近原生应用的事。 值得关注的是,其他标准也能并且将会使用service worker,例如:

+

未来 service workers 能够用来做更多使 web 平台接近原生应用的事。 值得关注的是,其他标准也能并且将会使用 service worker,例如:

@@ -102,17 +102,17 @@

接口

{{domxref("CacheStorage") }} {{Experimental_Inline}}
表示{{domxref("Cache")}}对象的存储。提供一个所有命名缓存的主目录,{{domxref("ServiceWorker")}}可以访问并维护名字字符串到{{domxref("Cache")}}对象的映射。
{{domxref("Client") }} {{Experimental_Inline}}
-
表示service worker client的作用域。一个service worker client可以是浏览器上下文的一个文档,也可以是一个由活动worker控制的{{domxref("SharedWorker")}}。
+
表示 service worker client 的作用域。一个 service worker client 可以是浏览器上下文的一个文档,也可以是一个由活动 worker 控制的{{domxref("SharedWorker")}}。
{{domxref("Clients") }} {{Experimental_Inline}}
-
表示一个{{domxref("Client")}}对象容器,是访问当前源的活动service worker clients的主要途径。
+
表示一个{{domxref("Client")}}对象容器,是访问当前源的活动 service worker clients 的主要途径。
{{domxref("ExtendableEvent") }} {{Experimental_Inline}}
-
扩展被分发到{{domxref("ServiceWorkerGlobalScope")}}的install和activate事件时序,作为service worker生命周期的一部分。这会确保任何功能型事件(如{{domxref("FetchEvent")}})不被分发到{{domxref("ServiceWorker")}},直到它更新了数据库架构、删除过期缓存项等等以后。
+
扩展被分发到{{domxref("ServiceWorkerGlobalScope")}}的install 和 activate事件时序,作为 service worker 生命周期的一部分。这会确保任何功能型事件(如{{domxref("FetchEvent")}})不被分发到{{domxref("ServiceWorker")}},直到它更新了数据库架构、删除过期缓存项等等以后。
{{DOMxRef("ExtendableMessageEvent")}} {{Experimental_Inline}}
The event object of a {{event("message_(ServiceWorker)","message")}} event fired on a service worker (when a channel message is received on the {{DOMxRef("ServiceWorkerGlobalScope")}} from another context) — extends the lifetime of such events.
{{domxref("FetchEvent") }}{{Experimental_Inline}}
-
传递给{{domxref("ServiceWorkerGlobalScope.onfetch")}}处理函数的参数,FetchEvent代表一个在{{domxref("ServiceWorker")}}的{{domxref("ServiceWorkerGlobalScope")}}中分发的请求动作。它包含关于请求和响应的结果信息,并且提供{{domxref("FetchEvent.respondWith", "FetchEvent.respondWith()")}}方法,这个方法允许我们提供任意的响应返回到控制页面。
+
传递给{{domxref("ServiceWorkerGlobalScope.onfetch")}}处理函数的参数,FetchEvent 代表一个在{{domxref("ServiceWorker")}}的{{domxref("ServiceWorkerGlobalScope")}}中分发的请求动作。它包含关于请求和响应的结果信息,并且提供{{domxref("FetchEvent.respondWith", "FetchEvent.respondWith()")}}方法,这个方法允许我们提供任意的响应返回到控制页面。
{{domxref("InstallEvent") }}{{Experimental_Inline}}
-
传递给{{domxref("ServiceWorkerGlobalScope.oninstall", "oninstall")}}处理函数的参数,InstallEvent接口代表一个在{{domxref("ServiceWorker")}}的{{domxref("ServiceWorkerGlobalScope")}}中分发的安装动作,作为{{domxref("ExtendableEvent")}}的子事件,它保证诸如{{domxref("FetchEvent")}} 的功能性事件在安装过程中不会被分发。
+
传递给{{domxref("ServiceWorkerGlobalScope.oninstall", "oninstall")}}处理函数的参数,InstallEvent 接口代表一个在{{domxref("ServiceWorker")}}的{{domxref("ServiceWorkerGlobalScope")}}中分发的安装动作,作为{{domxref("ExtendableEvent")}}的子事件,它保证诸如{{domxref("FetchEvent")}} 的功能性事件在安装过程中不会被分发。
{{DOMxRef("NavigationPreloadManager")}} {{Experimental_Inline}}
Provides methods for managing the preloading of resources with a service worker.
{{domxref("Navigator.serviceWorker") }}
@@ -123,23 +123,23 @@

接口

{{domxref("ServiceWorker") }} {{Experimental_Inline}}
-
表示一个service worker。多个浏览的上下文(例如pages,workers等等)都能通过相同的ServiceWorker对象相关联。
+
表示一个 service worker。多个浏览的上下文 (例如 pages,workers 等等) 都能通过相同的ServiceWorker 对象相关联。
{{domxref("ServiceWorkerContainer") }} {{Experimental_Inline}}
-
提供一个在网络生态中把service worker 作为一个整体的对象,包括辅助注册,反注册以及更新服务工作者,并且访问service worker 的状态以及他们的注册信息。
+
提供一个在网络生态中把 service worker 作为一个整体的对象,包括辅助注册,反注册以及更新服务工作者,并且访问 service worker 的状态以及他们的注册信息。
{{domxref("ServiceWorkerGlobalScope") }}
-
表示service worker的全局执行上下文。
+
表示 service worker 的全局执行上下文。
{{domxref("ServiceWorkerMessageEvent")}}{{Deprecated_Inline}}
包含关于一个发送给以navigator.serviceWorker为目标的事件信息。Note that this interface is deprecated in modern browsers. Service worker messages will now use the {{DOMxRef("MessageEvent")}} interface, for consistency with other web messaging features.
{{domxref("ServiceWorkerRegistration") }}
-
表示service worker的注册。
+
表示 service worker 的注册。
{{DOMxRef("ServiceWorkerState")}} {{Experimental_Inline}}
Associated with its ServiceWorker's state.
{{domxref("SyncEvent")}} {{non-standard_inline}}
-
传递给同步函数的参数,SyncEvent接口代表在ServiceWorker里{{domxref("ServiceWorkerGlobalScope")}}分发的同步动作。
+
传递给同步函数的参数,SyncEvent 接口代表在 ServiceWorker 里{{domxref("ServiceWorkerGlobalScope")}}分发的同步动作。
{{domxref("SyncManager")}} {{non-standard_inline}}
提供一个接口用于注册和返回{{domxref("SyncRegistration")}}对象。
{{domxref("WindowClient") }}{{Experimental_Inline}}
-
表示在浏览器上下文中记录的service worker客户端的作用域,被活动的工作者控制。是{{domxref("Client")}}对象的特殊类型,包含一些附加的方法和可用的属性。
+
表示在浏览器上下文中记录的 service worker 客户端的作用域,被活动的工作者控制。是{{domxref("Client")}}对象的特殊类型,包含一些附加的方法和可用的属性。

规范

diff --git a/files/zh-cn/web/api/service_worker_api/using_service_workers/index.html b/files/zh-cn/web/api/service_worker_api/using_service_workers/index.html index a59f2bf3b0688a..54785d3709a62d 100644 --- a/files/zh-cn/web/api/service_worker_api/using_service_workers/index.html +++ b/files/zh-cn/web/api/service_worker_api/using_service_workers/index.html @@ -19,13 +19,13 @@

背景

有一个困扰 web 用户多年的难题——丢失网络连接。即使是世界上最好的 web app,如果下载不了它,也是非常糟糕的体验。如今虽然已经有很多种技术去尝试着解决这一问题。而随着离线页面的出现,一些问题已经得到了解决。但是,最重要的问题是,仍然没有一个好的统筹机制对资源缓存和自定义的网络请求进行控制。

- 之前的尝试 — AppCache — 看起来是个不错的方法,因为它可以很容易地指定需要离线缓存的资源。但是,它假定你使用时会遵循诸多规则,如果你不严格遵循这些规则,它会把你的APP搞得一团糟。关于APPCache的更多详情,请看Jake Archibald的文章: Application Cache is a Douchebag.

+ 之前的尝试 — AppCache — 看起来是个不错的方法,因为它可以很容易地指定需要离线缓存的资源。但是,它假定你使用时会遵循诸多规则,如果你不严格遵循这些规则,它会把你的 APP 搞得一团糟。关于 APPCache 的更多详情,请看 Jake Archibald 的文章: Application Cache is a Douchebag.

-

注意:  从Firefox44起,当使用 AppCache 来提供离线页面支持时,会提示一个警告消息,来建议开发者使用 Service workers 来实现离线页面。({{bug("1204581")}}.)

+

注意:  从 Firefox44 起,当使用 AppCache 来提供离线页面支持时,会提示一个警告消息,来建议开发者使用 Service workers 来实现离线页面。({{bug("1204581")}}.)

-

Service worker 最终要去解决这些问题。虽然 Service Worker 的语法比 AppCache 更加复杂,但是你可以使用 JavaScript 更加精细地控制 AppCache 的静默行为。有了它,你可以解决目前离线应用的问题,同时也可以做更多的事。 Service Worker 可以使你的应用先访问本地缓存资源,所以在离线状态时,在没有通过网络接收到更多的数据前,仍可以提供基本的功能(一般称之为 Offline First)。这是原生APP 本来就支持的功能,这也是相比于 web app,原生 app 更受青睐的主要原因。

+

Service worker 最终要去解决这些问题。虽然 Service Worker 的语法比 AppCache 更加复杂,但是你可以使用 JavaScript 更加精细地控制 AppCache 的静默行为。有了它,你可以解决目前离线应用的问题,同时也可以做更多的事。 Service Worker 可以使你的应用先访问本地缓存资源,所以在离线状态时,在没有通过网络接收到更多的数据前,仍可以提供基本的功能(一般称之为 Offline First)。这是原生 APP 本来就支持的功能,这也是相比于 web app,原生 app 更受青睐的主要原因。

使用前的设置

@@ -33,11 +33,11 @@

使用前的设置

-

另外,你需要通过 HTTPS 来访问你的页面 — 出于安全原因,Service Workers 要求必须在 HTTPS 下才能运行。Github 是个用来测试的好地方,因为它就支持HTTPS。为了便于本地开发,localhost 也被浏览器认为是安全源。

+

另外,你需要通过 HTTPS 来访问你的页面 — 出于安全原因,Service Workers 要求必须在 HTTPS 下才能运行。Github 是个用来测试的好地方,因为它就支持 HTTPS。为了便于本地开发,localhost 也被浏览器认为是安全源。

基本架构

@@ -47,9 +47,9 @@

基本架构

  • service worker URL 通过 {{domxref("serviceWorkerContainer.register()")}} 来获取和注册。
  • 如果注册成功,service worker 就在 {{domxref("ServiceWorkerGlobalScope") }} 环境中运行; 这是一个特殊类型的 worker 上下文运行环境,与主运行线程(执行脚本)相独立,同时也没有访问 DOM 的能力。
  • service worker 现在可以处理事件了。
  • -
  • 受 service worker 控制的页面打开后会尝试去安装 service worker。最先发送给 service worker 的事件是安装事件(在这个事件里可以开始进行填充 IndexDB和缓存站点资源)。这个流程同原生 APP 或者 Firefox OS APP 是一样的 — 让所有资源可离线访问。
  • +
  • 受 service worker 控制的页面打开后会尝试去安装 service worker。最先发送给 service worker 的事件是安装事件 (在这个事件里可以开始进行填充 IndexDB 和缓存站点资源)。这个流程同原生 APP 或者 Firefox OS APP 是一样的 — 让所有资源可离线访问。
  • 当 oninstall 事件的处理程序执行完毕后,可以认为 service worker 安装完成了。
  • -
  • 下一步是激活。当 service worker 安装完成后,会接收到一个激活事件(activate event)。 onactivate 主要用途是清理先前版本的 service worker 脚本中使用的资源。
  • +
  • 下一步是激活。当 service worker 安装完成后,会接收到一个激活事件 (activate event)。 onactivate 主要用途是清理先前版本的 service worker 脚本中使用的资源。
  • Service Worker 现在可以控制页面了,但仅是在 register()  成功后的打开的页面。也就是说,页面起始于有没有 service worker ,且在页面的接下来生命周期内维持这个状态。所以,页面不得不重新加载以让 service worker 获得完全的控制。
  • @@ -63,9 +63,9 @@

    Promises

    Promises 是一种非常适用于异步操作的机制,一个操作依赖于另一个操作的成功执行。这是 service worker 的核心工作机制。

    - Promises 可以做很多事情。但现在,你只需要知道,如果有什么返回了一个promise,你可以在后面加上 .then() 来传入成功和失败的回调函数。或者,你可以在后面加上 .catch() 如果你想添加一个操作失败的回调函数。

    + Promises 可以做很多事情。但现在,你只需要知道,如果有什么返回了一个 promise,你可以在后面加上 .then() 来传入成功和失败的回调函数。或者,你可以在后面加上 .catch() 如果你想添加一个操作失败的回调函数。

    -

    接下来,让我们对比一下传统的同步回调结构,和异步promise结构,两者在功能上是等效的:

    +

    接下来,让我们对比一下传统的同步回调结构,和异步 promise 结构,两者在功能上是等效的:

    同步

    @@ -84,13 +84,13 @@

    异步

    console.log(err); }); -

    在上面第一个例子中,我们必须等待 myFunction( ) 执行完成,并返回 value值,在此之前,后续其它的代码无法执行。在第二个例子中,myFunction( ) 返回一个promise对象,下面的代码可以继续执行。当promise成功resolves后,then( ) 中的函数会异步地执行。
    +

    在上面第一个例子中,我们必须等待 myFunction( ) 执行完成,并返回 value 值,在此之前,后续其它的代码无法执行。在第二个例子中,myFunction( ) 返回一个 promise 对象,下面的代码可以继续执行。当 promise 成功 resolves 后,then( ) 中的函数会异步地执行。

    - 现在来举下实际的例子 — 如果我们想动态地加载图片,而且要在图片下载完成后再展示到页面上,要怎么实现呢?这是一个比较常见的场景,但是实现起来会有点麻烦。我们可以使用 .onload 事件处理程序,来实现图片的加载完成后再展示。但是如果图片的 onload事件发生在我们监听这个事件之前呢?我们可以使用 .complete来解决这个问题,但是仍然不够简洁,如果是多个图片该怎么处理呢?并且,这种方法仍然是同步的操作,会阻塞主线程。
    + 现在来举下实际的例子 — 如果我们想动态地加载图片,而且要在图片下载完成后再展示到页面上,要怎么实现呢?这是一个比较常见的场景,但是实现起来会有点麻烦。我们可以使用 .onload 事件处理程序,来实现图片的加载完成后再展示。但是如果图片的 onload 事件发生在我们监听这个事件之前呢?我们可以使用 .complete 来解决这个问题,但是仍然不够简洁,如果是多个图片该怎么处理呢?并且,这种方法仍然是同步的操作,会阻塞主线程。

    - 相比于以上方法,我们可以使用 promise 来实现。(可以看我们的 Promises test 示例源码, look at it running live.)

    + 相比于以上方法,我们可以使用 promise 来实现。(可以看我们的 Promises test 示例源码, look at it running live.)

    -

    {{note("service worker在实际使用中,会使用 caching 和 onfetch 等异步操作,而不是使用老旧的 XMLHttpRequest API。这里的例子使用 XMLHttpRequest API只是为了让你能将注意力集中于理解 Promise上。")}}

    +

    {{note("service worker 在实际使用中,会使用 caching 和 onfetch 等异步操作,而不是使用老旧的 XMLHttpRequest API。这里的例子使用 XMLHttpRequest API 只是为了让你能将注意力集中于理解 Promise 上。")}}

    function imgLoad(url) {
       return new Promise(function(resolve, reject) {
    @@ -114,9 +114,9 @@ 

    异步

    }); }
    -

    我们使用 Promise( ) 构造函数返回了一个新的promise对象,构造函数接收一个回调函数作为参数。这个回调函数包含两个参数,第一个为成功执行(resolve)的回调函数,第二个为执行失败(reject)的回调函数。我们将这两个回调函数在对应的时机执行。在这个例子中,resolve会在请求返回状态码200的时候执行,reject会在请求返回码为非200的时候执行。上面代码的其余部分基本都是XHR的相关操作,现在不需要过多关注。

    +

    我们使用 Promise( ) 构造函数返回了一个新的 promise 对象,构造函数接收一个回调函数作为参数。这个回调函数包含两个参数,第一个为成功执行 (resolve) 的回调函数,第二个为执行失败 (reject) 的回调函数。我们将这两个回调函数在对应的时机执行。在这个例子中,resolve 会在请求返回状态码 200 的时候执行,reject 会在请求返回码为非 200 的时候执行。上面代码的其余部分基本都是 XHR 的相关操作,现在不需要过多关注。

    -

    当我们调用 imgLoad( ) 函数时,传入要加载的图片url作为参数。然后,后面的代码与同步方式会有点不同:

    +

    当我们调用 imgLoad( ) 函数时,传入要加载的图片 url 作为参数。然后,后面的代码与同步方式会有点不同:

    var body = document.querySelector('body');
     var myImage = new Image();
    @@ -129,12 +129,12 @@ 

    异步

    console.log(Error); });
    -

    在函数调用后面,我们串联了 promise 的 then() 方法。then() 接受两个函数 —— 第一个函数在 promise 成功执行的情况下执行,而第二个函数则在 promise 执行失败情况下执行。当执行成功时,在 myImage 中显示图片,并追加到 body 里面(它的参数就是传递给 promise 的 resolve 方法的 request.response );当执行失败时,在控制台返回一个错误。

    +

    在函数调用后面,我们串联了 promise 的 then() 方法。then() 接受两个函数 —— 第一个函数在 promise 成功执行的情况下执行,而第二个函数则在 promise 执行失败情况下执行。当执行成功时,在 myImage 中显示图片,并追加到 body 里面 (它的参数就是传递给 promise 的 resolve 方法的 request.response );当执行失败时,在控制台返回一个错误。

    这些都是异步的。

    -

    注意: 你可以链式调用 promise,比如:
    +

    注意: 你可以链式调用 promise,比如:
    myPromise().then(success, failure).then(success).catch(failure);

    @@ -148,12 +148,12 @@

    Service workers demo




    - 你可以查看 Github上的源码, 也可以查看 在线示例。有一点需要我们重点关注的是 promise (查看 app.js 22-47行),这是一个你上面读到的 Promises test demo 里的一个修改版,它们有以下不同: 

    + 你可以查看 Github 上的源码, 也可以查看 在线示例。有一点需要我们重点关注的是 promise(查看 app.js 22-47 行),这是一个你上面读到的 Promises test demo 里的一个修改版,它们有以下不同: 

      -
    1. 原始的版本里,我们只传了一个我们想加载的图片的 URL 。在这个版本里,我们传了一个包含单个图片所有数据的 JSON (查看 image-list.js) 。这是因为每一个 promise reslove 的所有数据必须传给promise,因为它是异步的。如果你只传了 url ,那么当你 for 循环被遍历的时候你试图分别访问其他项,将不会有效的,因为 promise 的 resolve 不会和遍历(这个是同步的过程)同时完成。
    2. +
    3. 原始的版本里,我们只传了一个我们想加载的图片的 URL 。在这个版本里,我们传了一个包含单个图片所有数据的 JSON(查看 image-list.js)。这是因为每一个 promise reslove 的所有数据必须传给 promise,因为它是异步的。如果你只传了 url ,那么当你 for 循环被遍历的时候你试图分别访问其他项,将不会有效的,因为 promise 的 resolve 不会和遍历(这个是同步的过程)同时完成。
    4. 我们实际上用数组 resolve 了这些 promise,因为我们想让得到加载完的图片 blob 和 图片的名字、credit 和 alt 文本(查看 app.js  31-34 行)。Promises 只能 resolve 单个参数,所以你想 resolve 多个值的话,你需要用数组或对象。
    5. -
    6.  为了访问 promise resolved  的值,我们接着通过 then 函数进行获取(app.js 60-64行),这个有点古怪,但这就是 promise 工作的方式。
    7. +
    8.  为了访问 promise resolved  的值,我们接着通过 then 函数进行获取(app.js 60-64 行),这个有点古怪,但这就是 promise 工作的方式。

    现在来谈谈 Service workers

    @@ -176,7 +176,7 @@

    注册你的 worker

    1. 外面的代码块做了一个特性检查,在注册之前确保 service worker 是支持的。
    2. -
    3. 接着,我们使用 {{domxref("ServiceWorkerContainer.register()") }} 函数来注册站点的 service worker,service worker 只是一个驻留在我们的 app 内的一个 JavaScript 文件 (注意,这个文件的url 是相对于 origin, 而不是相对于引用它的那个 JS 文件)。
    4. +
    5. 接着,我们使用 {{domxref("ServiceWorkerContainer.register()") }} 函数来注册站点的 service worker,service worker 只是一个驻留在我们的 app 内的一个 JavaScript 文件 (注意,这个文件的 url 是相对于 origin, 而不是相对于引用它的那个 JS 文件)。
    6. scope 参数是选填的,可以被用来指定你想让 service worker 控制的内容的子目录。在这个例子里,我们指定了 '/sw-test/',表示 app 的 origin 下的所有内容。如果你留空的话,默认值也是这个值, 我们在指定只是作为例子。
    7. .then() 函数链式调用我们的 promise,当 promise resolve 的时候,里面的代码就会执行。
    8. 最后面我们链了一个 .catch() 函数,当 promise rejected 才会执行。
    9. @@ -184,14 +184,14 @@

      注册你的 worker

      这就注册了一个 service worker,它工作在 worker context,所以没有访问 DOM 的权限。在正常的页面之外运行 service worker 的代码来控制它们的加载。

      -

      单个 service worker 可以控制很多页面。每个你的 scope 里的页面加载完的时候,安装在页面的 service worker 可以控制它。牢记你需要小心 service worker 脚本里的全局变量: 每个页面不会有自己独有的worker。

      +

      单个 service worker 可以控制很多页面。每个你的 scope 里的页面加载完的时候,安装在页面的 service worker 可以控制它。牢记你需要小心 service worker 脚本里的全局变量: 每个页面不会有自己独有的 worker。

      注意: 你的 service worker 函数像一个代理服务器一样,允许你修改请求和响应,用他们的缓存替代它们等等。

      -

      注意: 关于 service workers 一个很棒的事情就是,如果你用像上面一样的浏览器特性检测方式检测发现浏览器并不支持SW,你还是可以正常地在线使用页面。与此同时,如果你在一个页面上同时使用 AppCache 和 SW , 不支持 SW 但是支持 AppCache  的浏览器,可以使用 AppCache,如果都支持的话,则会采用 SW

      +

      注意: 关于 service workers 一个很棒的事情就是,如果你用像上面一样的浏览器特性检测方式检测发现浏览器并不支持 SW,你还是可以正常地在线使用页面。与此同时,如果你在一个页面上同时使用 AppCache 和 SW , 不支持 SW 但是支持 AppCache  的浏览器,可以使用 AppCache,如果都支持的话,则会采用 SW

      为什么我的 service worker 注册失败了?

      @@ -200,8 +200,8 @@

      为什么我的 servi
      1. 你没有在 HTTPS 下运行你的程序
      2. -
      3. service worker文件的地址没有写对— 需要相对于 origin , 而不是 app 的根目录。在我们的例子例, service worker 是在 https://mdn.github.io/sw-test/sw.js,app 的根目录是 https://mdn.github.io/sw-test/。应该写成 /sw-test/sw.js 而非 /sw.js.
      4. -
      5.  service worker 在不同的 origin 而不是你的app的,这是不被允许的。
      6. +
      7. service worker 文件的地址没有写对— 需要相对于 origin , 而不是 app 的根目录。在我们的例子例, service worker 是在 https://mdn.github.io/sw-test/sw.js,app 的根目录是 https://mdn.github.io/sw-test/。应该写成 /sw-test/sw.js 而非 /sw.js.
      8. +
      9.  service worker 在不同的 origin 而不是你的 app 的,这是不被允许的。

      @@ -211,7 +211,7 @@

      为什么我的 servi
      • service worker 只能抓取在 service worker scope 里从客户端发出的请求。
      • 最大的 scope 是 service worker 所在的地址
      • -
      • 如果你的 service worker 被激活在一个有 Service-Worker-Allowed header 的客户端,你可以为service worker 指定一个最大的 scope 的列表。
      • +
      • 如果你的 service worker 被激活在一个有 Service-Worker-Allowed header 的客户端,你可以为 service worker 指定一个最大的 scope 的列表。
      • 在 Firefox, Service Worker APIs 在用户在 private browsing mode 下会被隐藏而且无法使用。
      @@ -219,7 +219,7 @@

      安装和激活:填充你的缓

      在你的 service worker 注册之后,浏览器会尝试为你的页面或站点安装并激活它。 

      - install 事件会在注册完成之后触发。install 事件一般是被用来填充你的浏览器的离线缓存能力。为了达成这个目的,我们使用了 Service Worker 的新的标志性的存储 API — {{domxref("cache")}} — 一个 service worker 上的全局对象,它使我们可以存储网络响应发来的资源,并且根据它们的请求来生成key。这个 API 和浏览器的标准的缓存工作原理很相似,但是是特定你的域的。它会一直持久存在,直到你告诉它不再存储,你拥有全部的控制权。

      + install 事件会在注册完成之后触发。install 事件一般是被用来填充你的浏览器的离线缓存能力。为了达成这个目的,我们使用了 Service Worker 的新的标志性的存储 API — {{domxref("cache")}} — 一个 service worker 上的全局对象,它使我们可以存储网络响应发来的资源,并且根据它们的请求来生成 key。这个 API 和浏览器的标准的缓存工作原理很相似,但是是特定你的域的。它会一直持久存在,直到你告诉它不再存储,你拥有全部的控制权。

      注意: Cache API 并不被每个浏览器支持。(查看 Browser support 部分了解更多信息。) 如果你现在就想使用它,可以考虑采用一个 polyfill,比如  Google topeka demo,或者把你的资源存储在 IndexedDB 中。

      @@ -247,7 +247,7 @@

      安装和激活:填充你的缓 });
        -
      1. 这里我们 新增了一个 install 事件监听器,接着在事件上接了一个{{domxref("ExtendableEvent.waitUntil()") }}  方法——这会确保Service Worker 不会在 waitUntil() 里面的代码执行完毕之前安装完成。
      2. +
      3. 这里我们 新增了一个 install 事件监听器,接着在事件上接了一个{{domxref("ExtendableEvent.waitUntil()") }}  方法——这会确保 Service Worker 不会在 waitUntil() 里面的代码执行完毕之前安装完成。
      4. 在 waitUntil() 内,我们使用了 caches.open() 方法来创建了一个叫做 v1 的新的缓存,将会是我们的站点资源缓存的第一个版本。它返回了一个创建缓存的 promise,当它 resolved 的时候,我们接着会调用在创建的缓存示例上的一个方法  addAll(),这个方法的参数是一个由一组相对于 origin 的 URL 组成的数组,这些 URL 就是你想缓存的资源的列表。
      5. 如果 promise 被 rejected,安装就会失败,这个 worker 不会做任何事情。这也是可以的,因为你可以修复你的代码,在下次注册发生的时候,又可以进行尝试。
      6. 当安装成功完成之后, service worker 就会激活。在第一次你的 service worker 注册/激活时,这并不会有什么不同。但是当  service worker 更新 (稍后查看 更新你的 service worker 部分) 的时候 ,就不太一样了。
      7. @@ -286,9 +286,9 @@

        自定义请求的响应

        ); }); -

        caches.match(event.request) 允许我们对网络请求的资源和 cache 里可获取的资源进行匹配,查看是否缓存中有相应的资源。这个匹配通过 url 和 vary header进行,就像正常的 http 请求一样。

        +

        caches.match(event.request) 允许我们对网络请求的资源和 cache 里可获取的资源进行匹配,查看是否缓存中有相应的资源。这个匹配通过 url 和 vary header 进行,就像正常的 http 请求一样。

        -

        让我们看看我们在定义我们的方法时的一些其他的选项 (查看 Fetch API documentation 了解更多有关 {{domxref("Request")}} 和 {{domxref("Response")}} 对象的更多信息。)

        +

        让我们看看我们在定义我们的方法时的一些其他的选项(查看 Fetch API documentation 了解更多有关 {{domxref("Request")}} 和 {{domxref("Response")}} 对象的更多信息。)

        1. @@ -337,7 +337,7 @@

          恢复失败的请求

          ); }); -

          如果 promise reject了, catch() 函数会执行默认的网络请求,意味着在网络可用的时候可以直接像服务器请求资源。

          +

          如果 promise reject 了, catch() 函数会执行默认的网络请求,意味着在网络可用的时候可以直接像服务器请求资源。

          如果我们足够聪明的话,我们就不会只是从服务器请求资源,而且还会把请求到的资源保存到缓存中,以便将来离线时所用!这意味着如果其他额外的图片被加入到  Star Wars 图库里,我们的 app 会自动抓取它们。下面就是这个诀窍:

          diff --git a/files/zh-cn/web/api/serviceworkercontainer/controller/index.html b/files/zh-cn/web/api/serviceworkercontainer/controller/index.html index 6cfc6a2b5219f9..c3e83b1232f8bb 100644 --- a/files/zh-cn/web/api/serviceworkercontainer/controller/index.html +++ b/files/zh-cn/web/api/serviceworkercontainer/controller/index.html @@ -5,7 +5,7 @@ ---
          {{SeeCompatTable}}{{APIRef("Service Workers API")}}
          -

          当状态为activated 时, {{domxref("ServiceWorkerContainer")}} 接口的只读属性 controller 返回一个 {{domxref("ServiceWorker")}} 对象(与 {{domxref("ServiceWorkerRegistration.active")}} 返回的对象是同一个)。当页面强制刷新 (Shift + refresh) 或不存在active worder时,该属性返回 null 。

          +

          当状态为activated 时, {{domxref("ServiceWorkerContainer")}} 接口的只读属性 controller 返回一个 {{domxref("ServiceWorker")}} 对象(与 {{domxref("ServiceWorkerRegistration.active")}} 返回的对象是同一个)。当页面强制刷新 (Shift + refresh) 或不存在 active worder 时,该属性返回 null 。

          语法

          @@ -14,7 +14,7 @@

          语法

          -

          一个{{domxref("ServiceWorker")}}对象.

          +

          一个{{domxref("ServiceWorker")}}对象。

          示例

          diff --git a/files/zh-cn/web/api/serviceworkercontainer/index.html b/files/zh-cn/web/api/serviceworkercontainer/index.html index 9cab0e783cc845..662210904bd858 100644 --- a/files/zh-cn/web/api/serviceworkercontainer/index.html +++ b/files/zh-cn/web/api/serviceworkercontainer/index.html @@ -16,20 +16,20 @@ ---

          {{SeeCompatTable}}{{APIRef("Service Workers API")}} 

          -

          ServiceWorkerContainer接口为 service worker提供一个容器般的功能,包括对service worker的注册,卸载 ,更新和访问service worker的状态,以及他们的注册者

          +

          ServiceWorkerContainer接口为 service worker 提供一个容器般的功能,包括对 service worker 的注册,卸载 ,更新和访问 service worker 的状态,以及他们的注册者

          -

          主要是{{domxref("ServiceWorkerContainer.register", "ServiceWorkerContainer.register(scriptURL, scope[, base])")}}提供一个注册service worker的方法,{{domxref("ServiceWorkerContainer.controller")}}将获取当前控制页面网络的service worker

          +

          主要是{{domxref("ServiceWorkerContainer.register", "ServiceWorkerContainer.register(scriptURL, scope[, base])")}}提供一个注册 service worker 的方法,{{domxref("ServiceWorkerContainer.controller")}}将获取当前控制页面网络的 service worker

          ?属性

          {{domxref("ServiceWorkerContainer.controller")}} {{readonlyinline}}
          -
          当?{{domxref("ServiceWorker")}}对象的state是active的时候,返回一个 {{domxref("ServiceWorker")}} ?对象 和{{domxref("ServiceWorkerRegistration.active")}})返回相同的对象。 如果当前的state都不是active或者强制刷新浏览器则返回null。
          +
          当?{{domxref("ServiceWorker")}}对象的 state 是 active 的时候,返回一个 {{domxref("ServiceWorker")}} ?对象 和{{domxref("ServiceWorkerRegistration.active")}}) 返回相同的对象。 如果当前的 state 都不是 active 或者强制刷新浏览器则返回 null。
          {{domxref("ServiceWorkerContainer.ready")}} {{readonlyinline}}
          -
          定义了一个serviceWorker是否准备好为一个页面服务,将返回一个 {{jsxref("Promise")}},并且这个 {{jsxref("Promise")}}永远不会 reject,这个 {{jsxref("Promise")}}会在{{domxref("ServiceWorkerRegistration")}} 获取到一个active的{{domxref("ServiceWorker")}}的时候被解决。
          +
          定义了一个 serviceWorker 是否准备好为一个页面服务,将返回一个 {{jsxref("Promise")}},并且这个 {{jsxref("Promise")}}永远不会 reject,这个 {{jsxref("Promise")}}会在{{domxref("ServiceWorkerRegistration")}} 获取到一个 active 的{{domxref("ServiceWorker")}}的时候被解决。
           
          @@ -37,11 +37,11 @@

          ?事件

          {{domxref("ServiceWorkerContainer.oncontrollerchange")}}
          -
          在{{domxref("ServiceWorkerRegistration")}}获取到一个新的active的{{domxref("ServiceWorker")}}对象的时候被触发
          +
          在{{domxref("ServiceWorkerRegistration")}}获取到一个新的 active 的{{domxref("ServiceWorker")}}对象的时候被触发
          {{domxref("ServiceWorkerContainer.onerror")}}
          -
          当service workers中出现错误的时候被触发
          +
          当 service workers 中出现错误的时候被触发
          {{domxref("ServiceWorkerContainer.onmessage")}}
          -
          当{{domxref("ServiceWorkerContainer")}}  对象接受到一个message消息的时候被触发,message由{{domxref("MessagePort.postMessage()")}}发出
          +
          当{{domxref("ServiceWorkerContainer")}}  对象接受到一个 message 消息的时候被触发,message 由{{domxref("MessagePort.postMessage()")}}发出

          ?方法

          @@ -50,14 +50,14 @@

          ?方法

          {{domxref("ServiceWorkerContainer.register", "ServiceWorkerContainer.register()")}} 
          创建或者更新一个{{domxref("ServiceWorkerRegistration")}} 用给定的scriptURL
          {{domxref("ServiceWorkerContainer.getRegistration()")}}
          -
          根据当前网页的URL与当前service worker的scope Url的匹配,返回一个 {{domxref("ServiceWorkerRegistration")}}对象,如果不能返回一个 {{domxref("ServiceWorkerRegistration")}},则返回一个{{jsxref("Promise")}}。
          +
          根据当前网页的 URL 与当前 service worker 的 scope Url 的匹配,返回一个 {{domxref("ServiceWorkerRegistration")}}对象,如果不能返回一个 {{domxref("ServiceWorkerRegistration")}},则返回一个{{jsxref("Promise")}}。
          {{domxref("ServiceWorkerContainer.getRegistrations()")}}
          返回所有的{{domxref("ServiceWorkerRegistration")}}对象,如果不能返回一个 {{domxref("ServiceWorkerRegistration")}},则返回一个{{jsxref("Promise")}}。

          ?举例

          -

          ?代码是service worker fallback-response sample (see fallback-response live)的其中一段. ?首先检查浏览器是否支持serviceWorker. 代码创建了一个serviceWorker,并且打印出来当前页面的serviceWorker的?是否接管了页面的网络状态. 如果没有需要刷新页面再次查看.  代码也处理了注册失败的情况

          +

          ?代码是service worker fallback-response sample (see fallback-response live) 的其中一段. ?首先检查浏览器是否支持 serviceWorker. 代码创建了一个 serviceWorker,并且打印出来当前页面的 serviceWorker 的?是否接管了页面的网络状态。如果没有需要刷新页面再次查看.  代码也处理了注册失败的情况

          if ('serviceWorker' in navigator) {
             navigator.serviceWorker.register('service-worker.js', {scope: './'}).then(function() {
          diff --git a/files/zh-cn/web/api/serviceworkercontainer/register/index.html b/files/zh-cn/web/api/serviceworkercontainer/register/index.html
          index 32777ce6f01f23..289c5966f03fdd 100644
          --- a/files/zh-cn/web/api/serviceworkercontainer/register/index.html
          +++ b/files/zh-cn/web/api/serviceworkercontainer/register/index.html
          @@ -7,11 +7,11 @@
           ---
           

          {{SeeCompatTable}}{{APIRef("Service Workers API")}}

          -

          {{domxref("ServiceWorkerContainer")}} 接口的 register() 方法创建或更新一个给定scriptURL的ServiceWorkerRegistration 

          +

          {{domxref("ServiceWorkerContainer")}} 接口的 register() 方法创建或更新一个给定 scriptURL 的ServiceWorkerRegistration 

          -

          如果成功,一个服务工作者注册将提供的脚本URL与一个范围进行关联,后者用于导航匹配。如果该方法无法返回一个 ServiceWorkerRegistration,则返回一个 Promise

          +

          如果成功,一个服务工作者注册将提供的脚本 URL 与一个范围进行关联,后者用于导航匹配。如果该方法无法返回一个 ServiceWorkerRegistration,则返回一个 Promise

          -

          您可以从受控页无条件调用此方法, 即, 您不需要首先检查是否有一个有效的注册。

          +

          您可以从受控页无条件调用此方法, 即,您不需要首先检查是否有一个有效的注册。

          语法

          @@ -26,11 +26,11 @@

          参数

          scriptURL
          -
          service worker脚本的URL.
          +
          service worker 脚本的 URL.
          options {{optional_inline}}
          注册时提供选项的配置对象。 目前可用的选项包括:
            -
          • scope: 一个 {{domxref("USVString")}},表示定义service worker注册范围的URL ;service worker可以控制的URL范围。通常是相对URL。默认值是基于当前的location,并以此来解析传入的路径.
          • +
          • scope: 一个 {{domxref("USVString")}},表示定义 service worker 注册范围的 URL ;service worker 可以控制的 URL 范围。通常是相对 URL。默认值是基于当前的 location,并以此来解析传入的路径。
          From f636f9fa2c91dd7969d1155c8452438df2209f26 Mon Sep 17 00:00:00 2001 From: A1lo Date: Fri, 3 Jun 2022 14:13:05 +0800 Subject: [PATCH 2/3] Apply suggestions from code review --- files/zh-cn/web/api/service_worker_api/index.html | 4 ++-- .../zh-cn/web/api/serviceworkercontainer/register/index.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/files/zh-cn/web/api/service_worker_api/index.html b/files/zh-cn/web/api/service_worker_api/index.html index 919b1d08ab5f16..ca7b7f17e860b3 100644 --- a/files/zh-cn/web/api/service_worker_api/index.html +++ b/files/zh-cn/web/api/service_worker_api/index.html @@ -112,7 +112,7 @@

          接口

          {{domxref("FetchEvent") }}{{Experimental_Inline}}
          传递给{{domxref("ServiceWorkerGlobalScope.onfetch")}}处理函数的参数,FetchEvent 代表一个在{{domxref("ServiceWorker")}}的{{domxref("ServiceWorkerGlobalScope")}}中分发的请求动作。它包含关于请求和响应的结果信息,并且提供{{domxref("FetchEvent.respondWith", "FetchEvent.respondWith()")}}方法,这个方法允许我们提供任意的响应返回到控制页面。
          {{domxref("InstallEvent") }}{{Experimental_Inline}}
          -
          传递给{{domxref("ServiceWorkerGlobalScope.oninstall", "oninstall")}}处理函数的参数,InstallEvent 接口代表一个在{{domxref("ServiceWorker")}}的{{domxref("ServiceWorkerGlobalScope")}}中分发的安装动作,作为{{domxref("ExtendableEvent")}}的子事件,它保证诸如{{domxref("FetchEvent")}} 的功能性事件在安装过程中不会被分发。
          +
          传递给 {{domxref("ServiceWorkerGlobalScope.oninstall", "oninstall")}} 处理函数的参数,InstallEvent 接口代表一个在 {{domxref("ServiceWorker")}} 的 {{domxref("ServiceWorkerGlobalScope")}} 中分发的安装动作,作为 {{domxref("ExtendableEvent")}} 的子事件,它保证诸如 {{domxref("FetchEvent")}} 的功能性事件在安装过程中不会被分发。
          {{DOMxRef("NavigationPreloadManager")}} {{Experimental_Inline}}
          Provides methods for managing the preloading of resources with a service worker.
          {{domxref("Navigator.serviceWorker") }}
          @@ -123,7 +123,7 @@

          接口

          {{domxref("ServiceWorker") }} {{Experimental_Inline}}
          -
          表示一个 service worker。多个浏览的上下文 (例如 pages,workers 等等) 都能通过相同的ServiceWorker 对象相关联。
          +
          表示一个 service worker。多个浏览的上下文 (例如 pages、workers 等等) 都能通过相同的 ServiceWorker 对象相关联。
          {{domxref("ServiceWorkerContainer") }} {{Experimental_Inline}}
          提供一个在网络生态中把 service worker 作为一个整体的对象,包括辅助注册,反注册以及更新服务工作者,并且访问 service worker 的状态以及他们的注册信息。
          {{domxref("ServiceWorkerGlobalScope") }}
          diff --git a/files/zh-cn/web/api/serviceworkercontainer/register/index.html b/files/zh-cn/web/api/serviceworkercontainer/register/index.html index 289c5966f03fdd..92dc05d8e6b926 100644 --- a/files/zh-cn/web/api/serviceworkercontainer/register/index.html +++ b/files/zh-cn/web/api/serviceworkercontainer/register/index.html @@ -7,7 +7,7 @@ ---

          {{SeeCompatTable}}{{APIRef("Service Workers API")}}

          -

          {{domxref("ServiceWorkerContainer")}} 接口的 register() 方法创建或更新一个给定 scriptURL 的ServiceWorkerRegistration 

          +

          {{domxref("ServiceWorkerContainer")}} 接口的 register()方法创建或更新一个给定 scriptURL 的ServiceWorkerRegistration

          如果成功,一个服务工作者注册将提供的脚本 URL 与一个范围进行关联,后者用于导航匹配。如果该方法无法返回一个 ServiceWorkerRegistration,则返回一个 Promise

          From 42880408139f82e3da930dbc077b503157aa1200 Mon Sep 17 00:00:00 2001 From: A1lo Date: Fri, 3 Jun 2022 14:13:27 +0800 Subject: [PATCH 3/3] Update files/zh-cn/web/api/service_worker_api/using_service_workers/index.html --- .../web/api/service_worker_api/using_service_workers/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/zh-cn/web/api/service_worker_api/using_service_workers/index.html b/files/zh-cn/web/api/service_worker_api/using_service_workers/index.html index 54785d3709a62d..647f2c7ec332c7 100644 --- a/files/zh-cn/web/api/service_worker_api/using_service_workers/index.html +++ b/files/zh-cn/web/api/service_worker_api/using_service_workers/index.html @@ -84,7 +84,7 @@

          异步

          console.log(err); });
          -

          在上面第一个例子中,我们必须等待 myFunction( ) 执行完成,并返回 value 值,在此之前,后续其它的代码无法执行。在第二个例子中,myFunction( ) 返回一个 promise 对象,下面的代码可以继续执行。当 promise 成功 resolves 后,then( ) 中的函数会异步地执行。
          +

          在上面第一个例子中,我们必须等待 myFunction() 执行完成,并返回 value 值,在此之前,后续其它的代码无法执行。在第二个例子中,myFunction() 返回一个 promise 对象,下面的代码可以继续执行。当 promise 成功 resolves 后,then() 中的函数会异步地执行。

          现在来举下实际的例子 — 如果我们想动态地加载图片,而且要在图片下载完成后再展示到页面上,要怎么实现呢?这是一个比较常见的场景,但是实现起来会有点麻烦。我们可以使用 .onload 事件处理程序,来实现图片的加载完成后再展示。但是如果图片的 onload 事件发生在我们监听这个事件之前呢?我们可以使用 .complete 来解决这个问题,但是仍然不够简洁,如果是多个图片该怎么处理呢?并且,这种方法仍然是同步的操作,会阻塞主线程。