aboutsummaryrefslogtreecommitdiff
path: root/files/es/web/javascript/reference/operators/yield/index.html
blob: 1783cb6f50b8cfd1911d88172b6b43e26e1402c2 (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
---
title: yield
slug: Web/JavaScript/Reference/Operators/yield
tags:
  - Característica del lenguaje
  - ECMAScript 2015
  - Generadores
  - Iterador
  - JavaScript
  - Operador
translation_of: Web/JavaScript/Reference/Operators/yield
original_slug: Web/JavaScript/Referencia/Operadores/yield
---
<div>{{jsSidebar("Operadores")}}</div>

<p>La palabra clave <code>yield</code> se usa para pausar y reanudar una función generadora ({{jsxref("Statements/function*", "function*")}} o {{jsxref("Statements/Legacy_generator_function", "función generadora heredada")}}).</p>

<div>{{EmbedInteractiveExample("pages/js/expressions-yield.html", "taller")}}</div>

<div class="hidden">La fuente de este ejemplo interactivo se almacena en un repositorio de GitHub. Si deseas contribuir al proyecto de ejemplos interactivos, clona <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> y envíanos una solicitud de extracción.</div>

<h2 id="Sintaxis">Sintaxis</h2>

<pre class="syntaxbox notranslate">[<var>rv</var>] = <strong>yield</strong> [<var>expression</var>]</pre>

<dl>
 <dt><code><var>expression</var></code> {{optional_inline}}</dt>
 <dd>Define el valor que se devolverá desde la función generadora a través del {{jsxref("Iteration_protocols", "protocolo iterador", "#El_protocolo_iterador")}}. Si se omite, devuelve <code>undefined</code> en su lugar.</dd>
 <dt><code><var>rv</var></code> {{optional_inline}}</dt>
 <dd>
 <p>Recupera el valor opcional pasado al método <code>next()</code> del generador para reanudar su ejecución.</p>
 </dd>
</dl>

<h2 id="Descripción">Descripción</h2>

<p>La palabra clave <code>yield</code> detiene la ejecución de la función del generador y el valor de la expresión que sigue a la palabra clave <code>yield</code> se devuelve al llamador del generador. Se puede considerar como una versión basada en un generador de la palabra clave <code>return</code>.</p>

<p><code>yield</code> solo se puede llamar directamente desde la función generadora que la contiene. No se puede llamar desde funciones anidadas o retrollamadas.</p>

<p>La palabra clave <code>yield</code> hace que la llamada al método <code>next()</code> del generador devuelva un objeto <code>IteratorResult</code> con dos propiedades: <code>value</code> y <code>done</code>. La propiedad <code>value</code> es el resultado de evaluar la expresión <code>yield</code>, y <code>done</code> es <code>false</code>, lo cual indica que la función generadora no se ha completado completamente.</p>

<p>Una vez en pausa en una expresión <code>yield</code>, la ejecución del código del generador permanece en pausa hasta que se llama al método <code>next()</code> del generador. Cada vez que se llama al método <code>next()</code> del generador, el generador reanuda la ejecución y se ejecuta hasta que alcanza uno de los siguientes:</p>

<ul>
 <li>Un <code>yield</code>, el cual hace que el generador vuelva a pausar y devuelva el nuevo valor del generador. La próxima vez que se llame a <code>next()</code>, la ejecución se reanudará con la instrucción inmediatamente después de <code>yield</code>.</li>
 <li>{{jsxref("Statements/throw", "throw")}} se usa para lanzar una excepción desde el generador. Esta detiene la ejecución del generador por completo y la ejecución se reanuda en el llamador (como suele ser el caso cuando se lanza una excepción).</li>
 <li>Se alcanza el final de la función generadora. En este caso, la ejecución del generador finaliza y se devuelve un <code>IteratorResult</code> al llamador en el que el <code>value</code> es {{jsxref("undefined")}} y <code>done</code> es <code>true</code>.</li>
 <li>Se alcanza una instrucción {{jsxref("Statements/return", "return")}}. En este caso, la ejecución del generador finaliza y se devuelve un <code>IteratorResult</code> al llamador en el que el <code>value</code> es el valor especificado por la instrucción <code>return</code> y <code>done</code> es <code>true</code>.</li>
</ul>

<p>Si se pasa un valor opcional al método <code>next()</code> del generador, ese valor se convierte en el valor devuelto por la operación <code>yield</code> actual del generador.</p>

<p>Entre la ruta del código del generador, sus operadores <code>yield</code> y la capacidad de especificar un nuevo valor inicial pasándolo a {{jsxref("Generator.prototype.next()")}}, los generadores ofrecen enorme poder y control.</p>

<div class="blockIndicator warning">
<p>Desafortunadamente, <code>next()</code> es asimétrico, pero eso no se puede evitar: siempre envía un valor al <code>yield</code> actualmente suspendido, pero devuelve el operando del siguiente <code>yield</code>.</p>
</div>

<h2 id="Ejemplos">Ejemplos</h2>

<h3 id="Usar_yield">Usar <code>yield</code></h3>

<p>El siguiente código es la declaración de una función generadora de ejemplo.</p>

<pre class="brush: js notranslate">function* countAppleSales () {
  let saleList = [3, 7, 5]
  for (let i = 0; i &lt; saleList.length; i++) {
    yield saleList[i]
  }
}</pre>

<p>Una vez que se define una función generadora, se puede usar construyendo un iterador como el siguiente.</p>

<pre class="brush: js notranslate">let appleStore = countAppleSales()  // Generator { }
console.log(appleStore.next())      // { value: 3, done: false }
console.log(appleStore.next())      // { value: 7, done: false }
console.log(appleStore.next())      // { value: 5, done: false }
console.log(appleStore.next())      // { value: undefined, done: true }</pre>

<p>También puedes enviar un valor con <code>next(value)</code> al generador. '<code>step</code>' se evalúa como un valor de retorno en esta sintaxis [<var>rv</var>] = <strong>yield</strong> [<var>expression</var>]</p>

<pre class="brush: js notranslate">function* counter(value) {
 let step;

 while (true) {
   step = yield ++value;

   if (step) {
     value += step;
   }
 }
}

const generatorFunc = counter(0);
console.log(generatorFunc.next().value);   // 1
console.log(generatorFunc.next().value);   // 2
console.log(generatorFunc.next().value);   // 3
console.log(generatorFunc.next(10).value); // 14
console.log(generatorFunc.next().value);   // 15
console.log(generatorFunc.next(10).value); // 26</pre>

<h2 id="Especificaciones">Especificaciones</h2>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Especificación</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{SpecName('ESDraft', '#prod-YieldExpression', 'Yield')}}</td>
  </tr>
 </tbody>
</table>

<h2 id="Compatibilidad_del_navegador">Compatibilidad del navegador</h2>

<div class="hidden">La tabla de compatibilidad de esta página se genera a partir de datos estructurados. Si deseas contribuir con los datos, consulta <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> y envíanos una solicitud de extracción.</div>

<p>{{Compat("javascript.operators.yield")}}</p>

<h2 id="Ve_también">Ve también</h2>

<ul>
 <li><a href="/en-US/docs/Web/JavaScript/Guide/The_Iterator_protocol">El protocolo <code>Iterator</code></a></li>
 <li>{{jsxref("Statements/function*", "function*")}}</li>
 <li>{{jsxref("Operators/function*", "function* expression")}}</li>
 <li>{{jsxref("Operators/yield*", "yield*")}}</li>
</ul>