编写你的应用程序(八)、进度事件

原文链接:https://developer.chrome.com/native-client/devguide/coding/progress-events

注意:已针对ChromeOS以外的平台公布了此处所述技术的弃用。
请访问我们的 迁移指南 了解详情。


进程事件

开发人员可以在Native Client中响应五种类型的事件:进度,消息,视图更改,焦点和输入事件(每个事件在下面的术语表中描述)。本节介绍如何监视进度事件(在加载和执行Native Client模块期间发生的事件)。本节假定您熟悉技术概述中提供的材料 。

load_progress示例说明了进度事件处理。您可以/pepper_<version>/examples/tutorial/load_progress/ 在Native Client SDK下载的目录中找到此代码。

模块加载和进度事件

Native Client运行时通过DOM进度事件在模块加载过程中报告一组状态更改。这组事件是建议的W3C Progress Events标准的直接端口(除了作为crash W3C标准的扩展的事件)。下表列出了Native Client运行时报告的事件类型:

事件 时间触发了 触发时 你可能会如何回应

loadstart

Native Client已开始加载Native Client模块。

一旦 实例化并初始化Native Client模块之后的第一个progress事件。 显示状态消息,例如“正在加载...”

progress

部分模块已加载。

零或更多 之后 loadstart 被派遣了。 显示进度条。

error

Native Client模块无法开始执行(包括模块初始化之前或期间的任何错误)。该lastError属性(稍后提到)提供了有关错误的详细信息(初始化失败,sel_ldr未启动,等等)。

零或一次 progress 调度最后一个 事件之后,或者在loadstart 没有progress 调度事件之后 。 通知用户应用程序无法加载。

abort

用户中止了NativeClient模块的加载。

零或一次 progress 调度最后一个 事件之后,或者在loadstart 没有progress 调度事件之后 。 你不太可能想要回应这个事件。

load

Native Client模块已成功加载,并已开始执行。(模块已成功初始化。)

零或一次 progress 调度最后一个 事件之后,或者在loadstart 没有progress 调度事件之后 。 删除进度条。

loadend

加载Native Client模块已停止。加载成功(load),失败(error)或中止(abort)。

一旦 在发送了一个errorabort或者 load 事件之后 。 表示加载结束(无论是否失败)。

crash

成功加载后,Native Client模块没有响应(在assert()或中死亡 exit())。此事件是Native Client独有的,不属于W3C Progress Events标准。该 exitStatus属性提供数字退出状态。

零或一次 过了一会儿loadend 通知用户该模块执行了非法操作。

成功加载模块的事件顺序如下:

事件已发送 ...然后尝试执行此任务
loadstart 加载清单文件
progress (第一次) 加载模块
progress (后续)  
load 开始执行模块
loadend  

加载期间发生的错误会记录到Google Chrome中的JavaScript控制台(选择菜单图标菜单图标>工具> JavaScript控制台)。

处理进度事件

您应该在<script>元素中添加事件侦听器,以便在<embed>解析元素之前侦听这些事件。例如,以下代码将load事件的侦听器添加到<div>也包含Native Client <embed>元素的父元素。首先,听众是附上的。然后,当侦听器<div>收到load事件时,将moduleDidLoad()调用JavaScript 函数。以下代码摘自以下示例getting_started/part1/

<!--
Load the published pexe.
Note: Since this module does not use any real-estate in the browser, its
width and height are set to 0.

Note: The <embed> element is wrapped inside a <div>, which has both a 'load'
and a 'message' event listener attached.  This wrapping method is used
instead of attaching the event listeners directly to the <embed> element to
ensure that the listeners are active before the NaCl module 'load' event
fires.  This also allows you to use PPB_Messaging.PostMessage() (in C) or
pp::Instance.PostMessage() (in C++) from within the initialization code in
your module.
-->
<div id="listener">
  <script type="text/javascript">
    var listener = document.getElementById('listener');
    listener.addEventListener('load', moduleDidLoad, true);
    listener.addEventListener('message', handleMessage, true);
  </script>

  <embed id="hello_tutorial"
         width=0 height=0
         src="hello_tutorial.nmf"
         type="application/x-pnacl" />
</div>

可以将事件侦听器添加到任何DOM对象。由于设置在最外层范围的侦听器捕获其包含元素的事件,因此可以在外部元素(包括<body>元素)上设置侦听器以处理来自内部元素的事件。有关更多信息,请参阅事件流捕获和 事件侦听器注册的W3规范。

显示负载状态

对进度事件的一个常见响应是显示已加载的模块的百分比。在load_progress示例中,当progress 触发事件时,将moduleLoadProgress调用该函数。此函数使用事件的lengthComputable,, loadedtotal属性(在建议的W3C Progress Events 标准中描述)来计算已加载模块的百分比。

function moduleLoadProgress(event) {
  var loadPercent = 0.0;
  var loadPercentString;
  if (event.lengthComputable && event.total > 0) {
    loadPercent = event.loaded / event.total * 100.0;
    loadPercentString = loadPercent + '%';
    common.logMessage('progress: ' + event.url + ' ' + loadPercentString +
                     ' (' + event.loaded + ' of ' + event.total + ' bytes)');
  } else {
    // The total length is not yet known.
    common.logMessage('progress: Computing...');
  }
}

lastError属性

所述<embed>元件具有lastError每当加载失败(一个被设置为一个信息串属性errorabort事件)时。

以下代码在<embed>元素之前添加事件侦听器,以捕获并处理加载Native Client模块时的错误。该 handleError()函数侦听error事件。发生错误时,此函数将lastError属性(embed_element.lastError)的内容作为警报打印。

function domContentLoaded(name, tc, config, width, height) {
  var listener = document.getElementById('listener');
  ...
  listener.addEventListener('error', moduleLoadError, true);
  ...
  common.createNaClModule(name, tc, config, width, height);
}

function moduleLoadError() {
  common.logMessage('error: ' + common.naclModule.lastError);
}

readyState属性

您可以使用该readyState属性来监视加载过程。如果您不关心单个进度事件的详细信息,或者您希望在不注册侦听器的情况下轮询当前加载状态,则此属性特别有用。readyState成功加载的进度值如下:

事件 readyState 值
(在任何事件之前) undefined
loadstart 1
progress 3
load 4
loadend 4

以下代码演示了如何使用该readyState属性监视加载过程 。和以前一样,添加事件侦听器的脚本在<embed>元素之前,以便在生成progress事件之前事件侦听器就位。

<html>
...
  <body id="body">
    <div id="status_div">
    </div>
    <div id="listener_div">
      <script type="text/javascript">
         var stat = document.getElementById('status_div');
         function handleEvent(e) {
           var embed_element = document.getElementById('my_embed');
           stat.innerHTML +=
           '<br>' + e.type + ': readyState = ' + embed_element.readyState;
         }
         var listener_element = document.getElementById('listener_div');
         listener_element.addEventListener('loadstart', handleEvent, true);
         listener_element.addEventListener('progress', handleEvent, true);
         listener_element.addEventListener('load', handleEvent, true);
         listener_element.addEventListener('loadend', handleEvent, true);
      </script>
      <embed
        name="naclModule"
        id="my_embed"
        width=0 height=0
        src="my_example.nmf"
        type="application/x-pnacl" />
    </div>
  </body>
</html>

exitStatus属性

如果应用程序调用,或崩溃exit(n), 则设置此只读属性abort()。由于NaCl模块是事件处理程序,因此无需exit(n)在正常执行中调用。如果模块退出或崩溃,crash则发出progress事件,该exitStatus属性将包含退出状态的数值:

  • 在显式调用的情况下exit(n),数值将是 n(在0到255之间)。
  • 在崩溃和调用的情况下abort(),数值将不为零,但确切的值将取决于所选的libc和目标体系结构,并且将来可能会更改。exitStatus在这些情况下,应用程序不应该依赖于稳定的值,但是该值可能对临时调试很有用。

CC-By 3.0许可下提供的内容

原文地址:https://www.cnblogs.com/SunkingYang/p/11049126.html