一直以来,Web 应用程序被局限在一个单线程世界中。这的确限制了开发人员在他们的代码中的作为,因为任何太复杂的东西都存在冻结应用程序 UI 的风险。通过将多线程引入 Web 应用程序,Web Workers 扭转了这一不利局面。这对于大部分应用程序逻辑都位于客户端的移动 Web 应用程序来说尤其有用。在本文中,您将了解如何使用 Web Workers 并发现哪些任务最适合它们。您还将看到如何使用其他 HTML 5 技术才能提高使用那些技术的效率。
开始
在本文中,您将使用最新的 Web 技术开发 Web 应用程序。这里的大部分代码只是 HTML、JavaScript 和 CSS — 所有 Web 开发人员的核心技术。所需的最重要的工具是用于进行测试的浏览器。本文大部分代码将在最新桌面浏览器上运行,但也有一些例外,我们将在文章中进行说明。当然,您也必须在移动浏览器上测试,为此,您需要最新的 iPhone 和 Android SDKs。本文将使用 iPhone SDK 3.1.3 和 Android SDK 2.1。本文的样例还将使用一个代理服务器来从浏览器访问远程服务。这个代理服务器是一个简单的 Java™ servlet,但也可以使用以 PHP、Ruby 以及其他语言编写的代理轻松替换。获取链接。
移动设备上的多线程 JavaScript
对于大多数开发人员来说,多线程或并发编程并不新鲜。但是,JavaScript 并不是一种支持并发编程的语言。JavaScript 的创建者认为,对于 JavaScript 这样旨在 Web 页面上执行简单任务的语言来说,并发编程容易出现问题,而且没有必要。然而,由于 Web 页面已经发展成为 Web 应用程序,使用 JavaScript 完成的任务的复杂程度已经大大增加,向 JavaScript 提出了与其他语言同等的要求。与此同时,使用其他支持并发编程的语言工作的开发人员经常面临伴随线程和 mutexes 这样的并发原语而来的超高复杂性的困扰。实际上,最近像 Scala、Clojure 和 F# 这样的几种新语言已经发展,它们都有可能简化并发性。
Web Worker 规范不只是向 JavaScript 和 Web 浏览器添加并发性,而且是以一种智慧的方式添加,这种方式将增加开发人员的能力,但不会向他们提供一种会导致问题的工具。 例如,多年来,桌面应用程序开发人员一直在使用多线程来支持他们的应用程序访问多个 I/O 资源,以避免在等待这些资源时冻结 UI。然而,当这些多线程更改共享的资源(包括 UI)时,这样的应用程序通常会出现问题,因为这种行为可能会导致应用程序冻结或崩溃。有了 Web Workers,这种情况就不会发生。衍生线程不能访问主 UI 线程访问的资源。事实上,衍生线程中的代码甚至不能与主 UI 线程执行的代码位于同一个文件中。
您甚至必须提供相应的外部文件作为构造函数的一部分,如 清单 1 所示。
这个进程使用三个资源:
在主线程上执行的 Web 页面 JavaScript(我称其为页面脚本)。Worker 对象,这是用于执行 Web Worker 函数的 JavaScript 对象。将在新衍生的线程上执行的脚本。我称其为 Worker 脚本。
让我们首先看看 清单 1 中的页面脚本。
立即学习“前端免费学习笔记(深入)”;
清单 1.在页面脚本中使用一个 Web Worker
var worker = new Worker("worker.js");worker.onmessage = function(message){ // do stuff};worker.postMessage(someDataToDoStuffWith);
登录后复制
在 清单 1 中,您可以看到使用 Web Workers 的三个基本步骤。首先,您创建一个 Worker 对象并向它传递将在新线程中执行的脚本的 URL。Worker 将执行的所有代码都必须包含在一个 Worker 脚本中,该脚本的 URL 将被传递到这个 Worker 的构造函数中。这个 Worker 脚本的 URL 受到浏览器的同源策略的限制 — 它必须来自加载这个页面的同一个域,该页面已加载正在创建这个 Web Worker 的页面脚本。
下一步是使用 onmessage 函数指定一个回调处理器函数。这个回调函数将在该 Worker 脚本执行后调用。message 是从该 Worker 脚本返回的数据,您可以随意处理该消息。回调函数在主线程上执行,因此它能访问 DOM。Worker 脚本在一个不同的线程内运行且不能访问 DOM,因此,您需要将来自这个 Worker 脚本的数据返回主线程,在那里,您可以安全地修改 DOM 来更新您的应用程序的 UI。这是 Web Workers 的无共享设计的关键特性。
清单 1 中的最后一行展示如何通过调用 Worker 的 postMessage 函数来启动它。这里,您传递一条消息(重申一下,它只是数据)给 Worker。当然,postMessage 是一个异步函数;您调用它,它就立即返回。
现在,检查这个 Worker 脚本。清单 2 中的代码是来自 清单 1 的 worker.js 文件的内容。
开始
在本文中,您将使用最新的 Web 技术开发 Web 应用程序。这里的大部分代码只是 HTML、JavaScript 和 CSS — 所有 Web 开发人员的核心技术。所需的最重要的工具是用于进行测试的浏览器。本文大部分代码将在最新桌面浏览器上运行,但也有一些例外,我们将在文章中进行说明。当然,您也必须在移动浏览器上测试,为此,您需要最新的 iPhone 和 Android SDKs。本文将使用 iPhone SDK 3.1.3 和 Android SDK 2.1。本文的样例还将使用一个代理服务器来从浏览器访问远程服务。这个代理服务器是一个简单的 Java™ servlet,但也可以使用以 PHP、Ruby 以及其他语言编写的代理轻松替换。获取链接。
移动设备上的多线程 JavaScript
对于大多数开发人员来说,多线程或并发编程并不新鲜。但是,JavaScript 并不是一种支持并发编程的语言。JavaScript 的创建者认为,对于 JavaScript 这样旨在 Web 页面上执行简单任务的语言来说,并发编程容易出现问题,而且没有必要。然而,由于 Web 页面已经发展成为 Web 应用程序,使用 JavaScript 完成的任务的复杂程度已经大大增加,向 JavaScript 提出了与其他语言同等的要求。与此同时,使用其他支持并发编程的语言工作的开发人员经常面临伴随线程和 mutexes 这样的并发原语而来的超高复杂性的困扰。实际上,最近像 Scala、Clojure 和 F# 这样的几种新语言已经发展,它们都有可能简化并发性。
Web Worker 规范不只是向 JavaScript 和 Web 浏览器添加并发性,而且是以一种智慧的方式添加,这种方式将增加开发人员的能力,但不会向他们提供一种会导致问题的工具。 例如,多年来,桌面应用程序开发人员一直在使用多线程来支持他们的应用程序访问多个 I/O 资源,以避免在等待这些资源时冻结 UI。然而,当这些多线程更改共享的资源(包括 UI)时,这样的应用程序通常会出现问题,因为这种行为可能会导致应用程序冻结或崩溃。有了 Web Workers,这种情况就不会发生。衍生线程不能访问主 UI 线程访问的资源。事实上,衍生线程中的代码甚至不能与主 UI 线程执行的代码位于同一个文件中。
您甚至必须提供相应的外部文件作为构造函数的一部分,如 清单 1 所示。
这个进程使用三个资源:
在主线程上执行的 Web 页面 JavaScript(我称其为页面脚本)。Worker 对象,这是用于执行 Web Worker 函数的 JavaScript 对象。将在新衍生的线程上执行的脚本。我称其为 Worker 脚本。
让我们首先看看 清单 1 中的页面脚本。
立即学习“前端免费学习笔记(深入)”;
清单 1.在页面脚本中使用一个 Web Worker
importScripts("utils.js");var workerState = {};onmessage = function(message){ workerState = message.data; // do stuff with the message postMessage({responseXml: this.responseText});}
登录后复制
在 清单 1 中,您可以看到使用 Web Workers 的三个基本步骤。首先,您创建一个 Worker 对象并向它传递将在新线程中执行的脚本的 URL。Worker 将执行的所有代码都必须包含在一个 Worker 脚本中,该脚本的 URL 将被传递到这个 Worker 的构造函数中。这个 Worker 脚本的 URL 受到浏览器的同源策略的限制 — 它必须来自加载这个页面的同一个域,该页面已加载正在创建这个 Web Worker 的页面脚本。
下一步是使用 onmessage 函数指定一个回调处理器函数。这个回调函数将在该 Worker 脚本执行后调用。message 是从该 Worker 脚本返回的数据,您可以随意处理该消息。回调函数在主线程上执行,因此它能访问 DOM。Worker 脚本在一个不同的线程内运行且不能访问 DOM,因此,您需要将来自这个 Worker 脚本的数据返回主线程,在那里,您可以安全地修改 DOM 来更新您的应用程序的 UI。这是 Web Workers 的无共享设计的关键特性。
清单 1 获取。当用户浏览这个交易列表选择感兴趣的商品时,您将使用 Web Workers 来预取这个附加信息。要从您的 Web 应用程序访问所有这些 eBay 数据,您需要通过使用一个泛型代理(generic proxy)来处理浏览器的同源策略。一个简单的 Java servlet 将用于这个代理,它包含在本文的代码中,但不在这里单独展示。相反,我们将把注意力集中在处理 Web Workers 的代码上。清单 3 展示了这个交易应用程序的基本 HTML 页面。
清单 3. 交易应用程序 HTML
Worker Deals Deals
More Deals
登录后复制
可以看出,这是一段非常简单的 HTML;它只是一个 shell。您使用 JavaScript 检索数据并生成 UI。这是移动 Web 应用程序的优化设计,因为它允许将所有代码和静态标记缓存到设备上,用户只需等待来自服务器的数据。注意,在 清单 3 中,一旦那个 body 加载,您就调用 loadDeals 函数,在那里,您将加载 清单 4 中的应用程序的初始数据。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。
发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/3126800.html