aboutsummaryrefslogtreecommitdiff
path: root/files/es/orphaned/usar_web_workers/index.html
blob: 5d3b471e0861780ae3c7cf051343ba8b3989ef31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
---
title: Usar web workers
slug: orphaned/Usar_web_workers
tags:
  - Firefox 3.5
  - Gecko 1.9.1
  - HTML5
  - JavaScript
  - Workers
  - para_revisar
original_slug: Usar_web_workers
---
<p>{{ gecko_minversion_header ("1.9.2") }}</p>
<p>Workers constituye un medio sencillo para que el contenido web ejecute secuencias de comandos en subprocesos en segundo plano. Una vez creado, un worker puede enviar mensajes a la tarea de generación mediante la publicación de mensajes en un controlador de eventos especificado por el creador.</p>
<p>El subproceso del worker puede realizar tareas sin interferir con la interfaz de usuario.  Además, pueden realizar E / S utilizando <code><a class="internal" href="/en/XMLHttpRequest" title="En/XMLHttpRequest">XMLHttpRequest</a></code> (aunque los atributos <code>responseXML</code> y <code>channel</code> siempre son nulos).</p>
<div class="note">
  <strong>Nota:</strong> como de costumbre, los subprocesos en segundo plano, incluyendo los workers, no pueden manipular el DOM.  Si las acciones adoptadas por el subproceso en segundo plano tienen que dar lugar a cambios en el DOM, deben enviar mensajes a sus creadores para hacer ese trabajo.</div>
<p>Consulta el documento de referencia <a class="internal" href="/En/DOM/Worker" title="En/DOM/Worker">Worker</a> , al que este artículo complementa ofreciendo ejemplos y añadiendo detalles. Para obtener una lista de funciones disponibles para workers, consulta <a href="/En/DOM/Worker/Functions_available_to_workers" title="En/DOM/Worker/Functions available to workers">Funciones disponibles para workers</a> .</p>
<h2 id="Acerca_de_la_seguridad_en_los_subprocesos">Acerca de la seguridad en los subprocesos</h2>
<p>La interfaz <code>Worker</code> genera subprocesos a nivel del sistema operativo y la simultaneidad puede producir efectos interesantes en el código si no tienes cuidado. Sin embargo, en el caso de web workers, los puntos de comunicación controlados cuidadosamente con otros subprocesos supone que en realidad sea muy difícil causar problemas de simultaneidad.  No hay acceso a componentes sin subprocesos seguros o al DOM y tienes que pasar datos específicos dentro y fuera de un subproceso a través de objetos serializados.  Así que te tienes que esforzar mucho para causar problemas en el código.</p>
<h2 id="Generar_un_worker">Generar un worker</h2>
<p>Crear un nuevo worker es simple.  Lo único que tienes que hacer es llamar al constructor <code>Worker()</code>, especificando el URI de un script para ejecutar en el subproceso del worker y, si deseas poder recibir las notificaciones del worker, establece la propiedad <code>onmessage</code> del worker a una función de manejador de evento adecuada.</p>
<pre class="brush: js">var myWorker = new Worker('my_worker.js');
myWorker.onmessage = function(event) {
  print("Llamado de nuevo por el worker\n");
};</pre>
<p>De forma alternativa, podemos usar <code>addEventListener()</code>:</p>
<pre class="brush: js">var worker = new Worker('my_worker.js');
worker.addEventListener('message', function(event) {
 console.log("Called back by the worker!\n");
}, false);

worker.postMessage(""); // Iniciar el worker.
</pre>
<p>La línea 1 de este ejemplo crea e inicia el subproceso del worker. La línea 2 establece el controlador <code>onmessage</code> para el worker a una función que se llama cuando éste pide su propia función <code>postMessage()</code>.</p>
<div class="note">
  <strong>Nota</strong>: La URI pasada como parámetro del constructor del <code>Worker</code> debe obedecer la política del <a href="/en/Same_origin_policy_for_JavaScript" title="Same origin policy for JavaScript">mismo origen o same-origin policy</a>. Actualmente hay un desacuerdo en los diferentes desarrolladores de navegadores acerca de si las URIs han de ser del mismo origen o no; Gecko 10.0 {{ geckoRelease("10.0") }} y posteriores permiten cualquier URI como script válido para workers, otros navegadores pueden no permitirlo.</div>
<h2 id="Generar_subworkers">Generar subworkers</h2>
<p>Los workers pueden generar más workers si así lo desean.  Los llamados subworkers deben estar alojados en el mismo origen que la página principal.  Además, los URI para los subworkers se resuelven en relación a la ubicación del worker principal y no en relación a la de la página propietaria.  Esto hace que sea más fácil que los workers realicen un seguimiento de dónde están sus dependencias.</p>
<h2 id="Tiempos_de_espera_e_intervalos">Tiempos de espera e intervalos</h2>
<p>Los workers pueden utilizar los tiempos de espera y los intervalos al igual que el proceso principal.  Esto puede ser útil, por ejemplo, si quieres hacer que tu subproceso del worker ejecute código de manera periódica en lugar de ininterrumpidamente.</p>
<p>Consulta <a class="internal" href="/en/DOM/window.setTimeout" title="En/DOM/Window.setTimeout"><code>setTimeout()</code></a>, <a class="internal" href="/en/DOM/window.clearTimeout" title="En/DOM/Window.clearTimeout"><code>clearTimeout()</code></a>, <a class="internal" href="/en/DOM/window.setInterval" title="En/DOM/Window.setInterval"><code>setInterval()</code></a> y <a class="internal" href="/en/DOM/window.clearInterval" title="En/DOM/Window.clearInterval"><code>clearInterval()</code></a> si deseas tener más detalles.</p>
<h2 id="Terminar_un_worker">Terminar un worker</h2>
<p>Si tienes que cancelar inmediatamente un worker que se está ejecutando, puedes hacerlo llamando al método <code>terminate()</code> del worker:</p>
<pre class="brush: js">myWorker.terminate();
</pre>
<p>El subproceso del worker se interrumpe inmediatamente y sin tener la posibilidad de terminar sus operaciones o limpiar por sí mismo.</p>
<p>Los workers pueden cerrarse llamando a su propio método {{ ifmethod("nsIWorkerScope", "close") }}.</p>
<h2 id="Gestión_de_errores">Gestión de errores</h2>
<p>Cuando se produce un error de ejecución en el worker, es llamado su controlador de enventos <code>onerror</code>.  Recibe un evento denominado <code>error</code> que implementa la interfaz <code>ErrorEvent</code>.  El evento no se lanza y se puede cancelar, para evitar que la acción predeterminada tenga lugar, el worker puede llamar al método <a class="internal" href="../../../../en/DOM/event.preventDefault" rel="internal"><code>preventDefault()</code></a> del evento de error.</p>
<p>El evento de error tiene los siguientes tres campos que son de interés:</p>
<dl>
  <dt>
    <code>message</code></dt>
  <dd>
    Un mensaje de error legible para el ojo humano.</dd>
  <dt>
    <code>filename</code></dt>
  <dd>
    El nombre del archivo de script en el que se produjo el error.</dd>
  <dt>
    <code>lineno</code></dt>
  <dd>
    El número de línea del archivo de script en el que se produjo el error.</dd>
</dl>
<h2 id="Acceder_al_objeto_navegador">Acceder al objeto navegador</h2>
<p>Los workers pueden acceder al objeto <code>navigator</code>, que está disponible dentro de su ámbito.  Contiene las siguientes cadenas de texto que pueden usarse para identificar el navegador, tal y como se puede hacer a partir de secuencias de comandos normales:</p>
<ul>
  <li><code>appName</code></li>
  <li><code>appVersion</code></li>
  <li><code>platform</code></li>
  <li><code>userAgent</code></li>
</ul>
<h2 id="Importar_de_secuencias_de_comandos_y_bibliotecas">Importar de secuencias de comandos y bibliotecas</h2>
<p>Los subprocesos de trabajo tienen acceso a una función global, importScripts (), que les permite importar secuencias de comandos de comandos o bibliotecas dentro de su ámbito.  Acepta como parámetros cero o más URI de recursos para la importación, todos los ejemplos siguientes son válidos:</p>
<pre class="brush: js">importScripts();                        /* no importa nada */
importScripts('foo.js');                /* importa solo "foo.js" */
importScripts('foo.js', 'bar.js');      /* importa dos scripts */
</pre>
<p>Firefox carga cada secuencia de comandos de la lista, luego los ejecuta para permitirles que se inicialicen ellos mismos.  Los objetos globales de cada secuencia de comandos pueden entonces ser utilizados por el worker.</p>
<div class="note">
  <strong>Nota:</strong> los scripts pueden ser descargados en cualquier orden, pero no se ejecutarán en el orden en que pasas los nombres de archivo a <code>importScripts()</code> .  Esto se realiza de forma sincrónica; <code>importScripts()</code> no retorna hasta que todas las secuencias de comandos se han cargado y ejecutado.</div>
<p> </p>
<h2 id="Ejemplos">Ejemplos</h2>
<p>Esta sección incluye varios ejemplos de cómo utilizar los DOM workers.</p>
<h3 id="Realizar_cálculos_en_segundo_plano">Realizar cálculos en segundo plano</h3>
<p>Una utilidad de los workers es permitir que tu código realice cálculos intensivos en el procesador sin bloquear el subproceso de interfaz de usuario.  En este ejemplo, un worker se utiliza para calcular los números de Fibonacci.</p>
<h4 id="El_código_JavaScript">El código JavaScript</h4>
<pre class="brush: js">var results = [];

function resultReceiver(event) {
  results.push(parseInt(event.data));
  if (results.length == 2) {
    postMessage(results[0] + results[1]);
  }
}

function errorReceiver(event) {
  throw event.data;
}

onmessage = function(event) {
  var n = parseInt(event.data);

  if (n == 0 || n == 1) {
    postMessage(n);
    return;
  }

  for (var i = 1; i &lt;= 2; i++) {
    var worker = new Worker("fibonacci.js");
    worker.onmessage = resultReceiver;
    worker.onerror = errorReceiver;
    worker.postMessage(n - i);
  }
 };</pre>
<p>La función <code>onmessage</code> es llamada cuando el código HTML llamada al <code>postMessage()</code> en el worker.  Esto inicia la recursividad, generando copias nuevas de sí mismo para controlar cada iteración del cálculo.</p>
<h4 id="El_código_HTML">El código HTML</h4>
<pre class="brush: html">&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;
&lt;html&gt;
  &lt;title&gt;Test threads fibonacci&lt;/title&gt;
  &lt;body&gt;

  &lt;div id="result"&gt;&lt;/div&gt;

  &lt;script language="javascript"&gt;

    var worker = new Worker("fibonacci.js");

    worker.onmessage = function(event) {
      document.getElementById("result").textContent = event.data;
      dump("Got: " + event.data + "\n");
    };

    worker.onerror = function(error) {
      dump("Worker error: " + error.message + "\n");
      throw error;
    };

    worker.postMessage("5");

  &lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
</pre>
<p>La página web crea un elemento <code>div</code> con el id. de cliente <code>result</code> , que se utiliza para mostrar el resultado, a continuación, genera el worker.  Tras generar el worker, el manejador<code>onmessage</code> está configurado para mostrar los resultados mediante el ajuste de los contenidos del elemento <code>div</code>, y el manejador <code>onerror</code> se establece para <a href="/en/Debugging_JavaScript#dump()" title="en/Debugging JavaScript#dump()">volcar</a> el mensaje de error.</p>
<p>Por último, se envía un mensaje al worker para iniciarlo.</p>
<p><a href="/samples/workers/fibonacci" title="samples/workers/fibonacci">Prueba este ejemplo</a> .</p>
<h3 id="Realizar_E_S_de_web_en_segundo_plano">Realizar E / S de web en segundo plano</h3>
<p>Puedes encontrar un ejemplo de esto en el artículo <a class="internal" href="/En/Using_workers_in_extensions" title="En/Using workers in extensions">Usar  workers en las extensiones</a> .</p>
<h3 id="Dividir_tareas_entre_varios_workers">Dividir tareas entre varios workers</h3>
<p>A medida que los equipos con varios núcleos se hacen cada vez más frecuentes, resulta útil dividir las tareas  complejas, desde el punto de vista computacional, entre varios workers, que a su vez pueden llevar a cabo esas tareas en núcleos de procesador múltiple.</p>
<p>el ejemplo se incluirá muy pronto</p>
<h3 id="Crear_workers_desde_dentro_de_los_workers">Crear workers desde dentro de los workers</h3>
<p>El ejemplo de Fibonacci mostrado anteriormente demuestra que los workers pueden, de hecho, generar más workers.  Esto facilita crear rutinas repetitivas.</p>
<h3 id="Enviar_objetos_a_los_workers">Enviar objetos a los workers</h3>
<p>Puede pasar con seguridad los objetos dentro y fuera de los workers que utilizan el método <code>postMessage()</code>, los objetos se convierten automáticamente en <a class="internal" href="/en/JSON" title="En/JSON">JSON</a> de manera interna.</p>
<pre class="brush: js">var onmessage = function(e) {
  postMessage(e.data);
};</pre>
<div class="note">
  <strong>Nota: los</strong> objetos que se introducen o se extraer de los workers no deben contener funciones o referencias cíclicas, ya que JSON no es compatible con ellas.</div>
<p>{{ CompatibilityTable() }}</p>
<div id="compat-desktop">
  <table class="compat-table">
    <tbody>
      <tr>
        <th>Característica</th>
        <th>Chrome</th>
        <th>Firefox (Gecko)</th>
        <th>Internet Explorer</th>
        <th>Opera</th>
        <th>Safari (WebKit)</th>
      </tr>
      <tr>
        <td>Workers dedicados</td>
        <td>3</td>
        <td>3.5 (1.9.1)</td>
        <td>10</td>
        <td>10.60</td>
        <td>4</td>
      </tr>
      <tr>
        <td>Workers compartidos</td>
        <td>5</td>
        <td>---</td>
        <td>---</td>
        <td>10.60</td>
        <td>5</td>
      </tr>
      <tr>
        <td>Pasar datos usando <a href="/en/DOM/The_structured_clone_algorithm" title="El algoritmo de clonación estructurada">clonación estructurada</a></td>
        <td>13</td>
        <td>8</td>
        <td>10</td>
        <td>11.50</td>
        <td>5.1</td>
      </tr>
      <tr>
        <td>Pasar datos usando <a class="external" href="http://dev.w3.org/html5/spec/common-dom-interfaces.html#transferable-objects" title="http://dev.w3.org/html5/spec/common-dom-interfaces.html#transferable-objects">objetos transferibles</a></td>
        <td>17 {{ property_prefix("webkit") }}</td>
        <td>---</td>
        <td>---</td>
        <td>---</td>
        <td>---</td>
      </tr>
    </tbody>
  </table>
</div>
<div id="compat-mobile">
  <table class="compat-table">
    <tbody>
      <tr>
        <th>Característica</th>
        <th>Android</th>
        <th>Chrome for Android</th>
        <th>Firefox Mobile (Gecko)</th>
        <th>IE Phone</th>
        <th>Opera Mobile</th>
        <th>Safari Mobile</th>
      </tr>
      <tr>
        <td>Workers dedicados</td>
        <td>---</td>
        <td>0.16</td>
        <td>---</td>
        <td>---</td>
        <td>11</td>
        <td>5</td>
      </tr>
      <tr>
        <td>Workers compartidos</td>
        <td>---</td>
        <td>{{ CompatNo() }}</td>
        <td>---</td>
        <td>---</td>
        <td>---</td>
        <td>---</td>
      </tr>
      <tr>
        <td>Pasar datos usando <a href="/en/DOM/The_structured_clone_algorithm" title="El algoritmo de clonación estructurada">clonación estructurada</a></td>
        <td>---</td>
        <td>0.16</td>
        <td>---</td>
        <td>---</td>
        <td>---</td>
        <td>---</td>
      </tr>
    </tbody>
  </table>
</div>
<h2 id="Consulta_también">Consulta también</h2>
<ul>
  <li>{{ spec("http://dev.w3.org/html5/workers/", "Especificación API de ficheros: Web Workers", "ED") }}</li>
  <li><a class="internal" href="/En/DOM/Worker" title="En/DOM/Worker">Worker</a> interface</li>
  <li><a class="internal" href="/En/DOM/SharedWorker" title="En/DOM/SharedWorker">SharedWorker</a> interface</li>
  <li><a href="/En/DOM/Worker/Functions_available_to_workers" title="En/DOM/Worker/Functions available to workers">Funciones disponibles para workers</a></li>
  <li><a class="external" href="http://www.html5rocks.com/en/tutorials/workers/basics/#toc-enviornment-subworkers" title="http://www.html5rocks.com/en/tutorials/workers/basics/#toc-enviornment-subworkers">HTML5Rocks - Lo básico sobre Web Workers</a></li>
</ul>
<p>{{ HTML5ArticleTOC() }}</p>
<p>{{ languages ( {"en": "En/Using_web_workers"} ) }}</p>